Bug Summary

File:src/usr.sbin/ldapd/schema.c
Warning:line 937, column 7
Null pointer passed as 1st argument to string comparison function

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name schema.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/ldapd/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/usr.sbin/ldapd -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/ldapd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/ldapd/schema.c
1/* $OpenBSD: schema.c,v 1.20 2022/10/12 11:57:40 jsg 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
32static int
33attr_oid_cmp(struct attr_type *a, struct attr_type *b)
34{
35 return strcasecmp(a->oid, b->oid);
36}
37
38static int
39obj_oid_cmp(struct object *a, struct object *b)
40{
41 return strcasecmp(a->oid, b->oid);
42}
43
44static int
45oidname_cmp(struct oidname *a, struct oidname *b)
46{
47 return strcasecmp(a->on_name, b->on_name);
48}
49
50static int
51symoid_cmp(struct symoid *a, struct symoid *b)
52{
53 return strcasecmp(a->name, b->name);
54}
55
56RB_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); }
;
57RB_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); }
;
58RB_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); }
;
59RB_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
61static struct attr_list *push_attr(struct attr_list *alist, struct attr_type *a);
62static struct obj_list *push_obj(struct obj_list *olist, struct object *obj);
63static struct name_list *push_name(struct name_list *nl, char *name);
64int is_oidstr(const char *oidstr);
65
66struct attr_type *
67lookup_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
79struct attr_type *
80lookup_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
88struct attr_type *
89lookup_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
96struct object *
97lookup_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
105struct object *
106lookup_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
118struct object *
119lookup_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 */
135char *
136lookup_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 */
177static struct symoid *
178push_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
202static struct attr_list *
203push_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
226static struct obj_list *
227push_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
250int
251is_oidstr(const char *oidstr)
252{
253 struct ber_oid oid;
254 return (ober_string2oid(oidstr, &oid) == 0);
255}
256
257static struct name_list *
258push_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
280static int
281schema_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
309static int
310schema_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
321static int
322findeol(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
342static int
343schema_lex(struct schema *schema, char **kw)
344{
345 char buf[8096];
346 char *p;
347 int quotec, next, c;
348
349 if (kw
11.1
'kw' is non-null, which participates in a condition later
35.1
'kw' is non-null
)
12
Taking true branch
36
Taking true branch
350 *kw = NULL((void *)0);
37
Null pointer value stored to 'kw'
351
352top:
353 p = buf;
354 while ((c = schema_getc(schema, 0)) == ' ' || c == '\t')
13
Assuming the condition is false
14
Assuming the condition is false
15
Loop condition is false. Execution continues on line 357
38
Assuming the condition is false
39
Assuming the condition is false
40
Loop condition is false. Execution continues on line 357
355 ; /* nothing */
356
357 if (c == '#')
16
Assuming the condition is false
17
Taking false branch
41
Assuming the condition is false
42
Taking false branch
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 == '*') {
18
Assuming the character is non-alphanumeric
19
Assuming the condition is false
20
Assuming the condition is false
21
Assuming the condition is false
22
Taking false branch
43
Assuming the character is non-alphanumeric
44
Assuming the condition is false
45
Assuming the condition is false
46
Assuming the condition is false
47
Taking false branch
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') {
23
Assuming the condition is false
24
Taking false branch
48
Assuming the condition is false
49
Taking false branch
416 schema->lineno++;
417 goto top;
418 }
419 if (c == EOF(-1))
25
Assuming the condition is false
26
Taking false branch
50
Assuming the condition is false
51
Taking false branch
420 return (0);
421 return (c);
422}
423
424struct schema *
425schema_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
441static void
442schema_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
457static int
458schema_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
481static int
482schema_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
493static int
494schema_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
517static int
518schema_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
529static struct name_list *
530schema_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
554fail:
555 free(kw);
556 /* FIXME: leaks nlist here */
557 return NULL((void *)0);
558}
559
560static void
561schema_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
573static struct attr_list *
574schema_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
617fail:
618 free(kw);
619 /* FIXME: leaks alist here */
620 return NULL((void *)0);
621}
622
623static struct obj_list *
624schema_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
664fail:
665 free(kw);
666 /* FIXME: leaks olist here */
667 return NULL((void *)0);
668}
669
670static int
671schema_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
699static int
700schema_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 kw = NULL((void *)0);
838 }
839
840 /* Check that a syntax is defined, either directly or
841 * indirectly via a superior attribute type.
842 */
843 sup = attr->sup;
844 while (attr->syntax == NULL((void *)0) && sup != NULL((void *)0)) {
845 attr->syntax = sup->syntax;
846 sup = sup->sup;
847 }
848 if (attr->syntax == NULL((void *)0)) {
849 schema_err(schema, "%s: no syntax defined", ATTR_NAME(attr)((attr)->names ? (((attr)->names)->slh_first)->name
: (attr)->oid)
);
850 goto fail;
851 }
852
853 /* If the attribute type doesn't explicitly define equality, check
854 * if any superior attribute type does.
855 */
856 sup = attr->sup;
857 while (attr->equality == NULL((void *)0) && sup != NULL((void *)0)) {
858 attr->equality = sup->equality;
859 sup = sup->sup;
860 }
861 /* Same thing with ordering matching rule. */
862 sup = attr->sup;
863 while (attr->ordering == NULL((void *)0) && sup != NULL((void *)0)) {
864 attr->ordering = sup->ordering;
865 sup = sup->sup;
866 }
867 /* ...and substring matching rule. */
868 sup = attr->sup;
869 while (attr->substr == NULL((void *)0) && sup != NULL((void *)0)) {
870 attr->substr = sup->substr;
871 sup = sup->sup;
872 }
873
874 if (schema_validate_match_rule(schema, attr, attr->equality, MATCH_EQUALITY) != 0 ||
875 schema_validate_match_rule(schema, attr, attr->ordering, MATCH_ORDERING) != 0 ||
876 schema_validate_match_rule(schema, attr, attr->substr, MATCH_SUBSTR) != 0)
877 goto fail;
878
879 return 0;
880
881fail:
882 free(kw);
883 if (attr != NULL((void *)0)) {
884 if (attr->oid != NULL((void *)0)) {
885 RB_REMOVE(attr_type_tree, &schema->attr_types, attr)attr_type_tree_RB_REMOVE(&schema->attr_types, attr);
886 free(attr->oid);
887 }
888 free(attr->desc);
889 free(attr);
890 }
891 return -1;
892}
893
894static int
895schema_parse_objectclass(struct schema *schema)
896{
897 struct object *obj = NULL((void *)0), *prev;
898 struct obj_ptr *optr;
899 struct name_list *xnames;
900 char *kw = NULL((void *)0);
901 int token, ret = 0;
902
903 if (schema_lex(schema, NULL((void *)0)) != '(')
9
Assuming the condition is false
10
Taking false branch
904 goto fail;
905
906 if (schema_lex(schema, &kw) != STRING1)
11
Calling 'schema_lex'
27
Returning from 'schema_lex'
28
Assuming the condition is false
29
Taking false branch
907 goto fail;
908
909 if ((obj = calloc(1, sizeof(*obj))) == NULL((void *)0)) {
30
Assuming the condition is false
31
Taking false branch
910 log_warn("calloc");
911 goto fail;
912 }
913 obj->kind = KIND_STRUCTURAL;
914
915 if (is_oidstr(kw))
32
Taking true branch
916 obj->oid = kw;
917 else {
918 obj->oid = lookup_symbolic_oid(schema, kw);
919 if (obj->oid == NULL((void *)0))
920 goto fail;
921 free(kw);
922 }
923 kw = NULL((void *)0);
924
925 prev = RB_INSERT(object_tree, &schema->objects, obj)object_tree_RB_INSERT(&schema->objects, obj);
926 if (prev
32.1
'prev' is equal to NULL
!= NULL((void *)0)) {
33
Taking false branch
927 schema_err(schema, "object class %s already defined", obj->oid);
928 goto fail;
929 }
930
931 while (ret == 0) {
34
Loop condition is true. Entering loop body
932 token = schema_lex(schema, &kw);
35
Calling 'schema_lex'
52
Returning from 'schema_lex'
933 if (token == ')')
53
Assuming the condition is false
54
Taking false branch
934 break;
935 else if (token != STRING1)
55
Assuming 'token' is equal to STRING
56
Taking false branch
936 goto fail;
937 if (strcasecmp(kw, "NAME") == 0) {
57
Null pointer passed as 1st argument to string comparison function
938 obj->names = schema_parse_names(schema);
939 if (obj->names == NULL((void *)0))
940 goto fail;
941 schema_link_obj_names(schema, obj);
942 } else if (strcasecmp(kw, "DESC") == 0) {
943 if (schema_lex(schema, &obj->desc) != STRING1)
944 goto fail;
945 } else if (strcasecmp(kw, "OBSOLETE") == 0) {
946 obj->obsolete = 1;
947 } else if (strcasecmp(kw, "SUP") == 0) {
948 obj->sup = schema_parse_objlist(schema);
949 if (obj->sup == NULL((void *)0))
950 goto fail;
951 } else if (strcasecmp(kw, "ABSTRACT") == 0) {
952 obj->kind = KIND_ABSTRACT;
953 } else if (strcasecmp(kw, "STRUCTURAL") == 0) {
954 obj->kind = KIND_STRUCTURAL;
955 } else if (strcasecmp(kw, "AUXILIARY") == 0) {
956 obj->kind = KIND_AUXILIARY;
957 } else if (strcasecmp(kw, "MUST") == 0) {
958 obj->must = schema_parse_attrlist(schema);
959 if (obj->must == NULL((void *)0))
960 goto fail;
961 } else if (strcasecmp(kw, "MAY") == 0) {
962 obj->may = schema_parse_attrlist(schema);
963 if (obj->may == NULL((void *)0))
964 goto fail;
965 } else if (strncasecmp(kw, "X-", 2) == 0) {
966 /* unknown extension, eat argument(s) */
967 xnames = schema_parse_names(schema);
968 if (xnames == NULL((void *)0))
969 goto fail;
970 schema_free_name_list(xnames);
971 } else {
972 schema_err(schema, "syntax error at token '%s'", kw);
973 goto fail;
974 }
975 free(kw);
976 kw = NULL((void *)0);
977 }
978
979 /* Verify the subclassing is allowed.
980 *
981 * Structural object classes cannot subclass auxiliary object classes.
982 * Auxiliary object classes cannot subclass structural object classes.
983 * Abstract object classes cannot derive from structural or auxiliary
984 * object classes.
985 */
986 if (obj->sup != NULL((void *)0)) {
987 SLIST_FOREACH(optr, obj->sup, next)for((optr) = ((obj->sup)->slh_first); (optr) != ((void *
)0); (optr) = ((optr)->next.sle_next))
{
988 if (obj->kind == KIND_STRUCTURAL &&
989 optr->object->kind == KIND_AUXILIARY) {
990 log_warnx("structural object class '%s' cannot"
991 " subclass auxiliary object class '%s'",
992 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)
);
993 goto fail;
994 }
995
996 if (obj->kind == KIND_AUXILIARY &&
997 optr->object->kind == KIND_STRUCTURAL) {
998 log_warnx("auxiliary object class '%s' cannot"
999 " subclass structural object class '%s'",
1000 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)
);
1001 goto fail;
1002 }
1003
1004 if (obj->kind == KIND_ABSTRACT &&
1005 optr->object->kind != KIND_ABSTRACT) {
1006 log_warnx("abstract object class '%s' cannot"
1007 " subclass non-abstract object class '%s'",
1008 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)
);
1009 goto fail;
1010 }
1011 }
1012 }
1013
1014 return 0;
1015
1016fail:
1017 free(kw);
1018 if (obj != NULL((void *)0)) {
1019 if (obj->oid != NULL((void *)0)) {
1020 RB_REMOVE(object_tree, &schema->objects, obj)object_tree_RB_REMOVE(&schema->objects, obj);
1021 free(obj->oid);
1022 }
1023 free(obj->desc);
1024 free(obj);
1025 }
1026 return -1;
1027}
1028
1029static int
1030schema_parse_objectidentifier(struct schema *schema)
1031{
1032 char *symname = NULL((void *)0), *symoid = NULL((void *)0);
1033 char *oid = NULL((void *)0);
1034
1035 if (schema_lex(schema, &symname) != STRING1)
1036 goto fail;
1037 if (schema_lex(schema, &symoid) != STRING1)
1038 goto fail;
1039
1040 if (is_oidstr(symoid)) {
1041 oid = symoid;
1042 symoid = NULL((void *)0);
1043 } else if ((oid = lookup_symbolic_oid(schema, symoid)) == NULL((void *)0))
1044 goto fail;
1045
1046 if (push_symbolic_oid(schema, symname, oid) == NULL((void *)0))
1047 goto fail;
1048
1049 free(symoid);
1050 return 0;
1051
1052fail:
1053 free(symname);
1054 free(symoid);
1055 free(oid);
1056 return -1;
1057}
1058
1059int
1060schema_parse(struct schema *schema, const char *filename)
1061{
1062 char *kw;
1063 int token, ret = 0;
1064
1065 log_debug("parsing schema file '%s'", filename);
1066
1067 if ((schema->fp = fopen(filename, "r")) == NULL((void *)0)) {
1
Assuming the condition is false
2
Taking false branch
1068 log_warn("%s", filename);
1069 return -1;
1070 }
1071 schema->filename = filename;
1072 schema->lineno = 1;
1073
1074 while (ret == 0) {
3
Loop condition is true. Entering loop body
1075 token = schema_lex(schema, &kw);
1076 if (token
3.1
'token' is equal to STRING
== STRING1) {
4
Taking true branch
1077 if (strcasecmp(kw, "attributetype") == 0)
5
Assuming the condition is false
6
Taking false branch
1078 ret = schema_parse_attributetype(schema);
1079 else if (strcasecmp(kw, "objectclass") == 0)
7
Taking true branch
1080 ret = schema_parse_objectclass(schema);
8
Calling 'schema_parse_objectclass'
1081 else if (strcasecmp(kw, "objectidentifier") == 0)
1082 ret = schema_parse_objectidentifier(schema);
1083 else {
1084 schema_err(schema, "syntax error at '%s'", kw);
1085 ret = -1;
1086 }
1087 if (ret == -1 && schema->error == 0)
1088 schema_err(schema, "syntax error");
1089 free(kw);
1090 } else if (token == 0) { /* EOF */
1091 break;
1092 } else {
1093 schema_err(schema, "syntax error");
1094 ret = -1;
1095 }
1096 }
1097
1098 fclose(schema->fp);
1099 schema->fp = NULL((void *)0);
1100 schema->filename = NULL((void *)0);
1101
1102 return ret;
1103}
1104
1105static int
1106schema_dump_names(const char *desc, struct name_list *nlist,
1107 char *buf, size_t size)
1108{
1109 struct name *name;
1110
1111 if (nlist == NULL((void *)0) || SLIST_EMPTY(nlist)(((nlist)->slh_first) == ((void *)0)))
1112 return 0;
1113
1114 if (strlcat(buf, " ", size) >= size ||
1115 strlcat(buf, desc, size) >= size)
1116 return -1;
1117
1118 name = SLIST_FIRST(nlist)((nlist)->slh_first);
1119 if (SLIST_NEXT(name, next)((name)->next.sle_next) == NULL((void *)0)) {
1120 /* single name, no parenthesis */
1121 if (strlcat(buf, " '", size) >= size ||
1122 strlcat(buf, name->name, size) >= size ||
1123 strlcat(buf, "'", size) >= size)
1124 return -1;
1125 } else {
1126 if (strlcat(buf, " ( ", size) >= size)
1127 return -1;
1128 SLIST_FOREACH(name, nlist, next)for((name) = ((nlist)->slh_first); (name) != ((void *)0); (
name) = ((name)->next.sle_next))
1129 if (strlcat(buf, "'", size) >= size ||
1130 strlcat(buf, name->name, size) >= size ||
1131 strlcat(buf, "' ", size) >= size)
1132 return -1;
1133 if (strlcat(buf, ")", size) >= size)
1134 return -1;
1135 }
1136
1137 return 0;
1138}
1139
1140static int
1141schema_dump_attrlist(const char *desc, struct attr_list *alist,
1142 char *buf, size_t size)
1143{
1144 struct attr_ptr *aptr;
1145
1146 if (alist == NULL((void *)0) || SLIST_EMPTY(alist)(((alist)->slh_first) == ((void *)0)))
1147 return 0;
1148
1149 if (strlcat(buf, " ", size) >= size ||
1150 strlcat(buf, desc, size) >= size)
1151 return -1;
1152
1153 aptr = SLIST_FIRST(alist)((alist)->slh_first);
1154 if (SLIST_NEXT(aptr, next)((aptr)->next.sle_next) == NULL((void *)0)) {
1155 /* single attribute, no parenthesis */
1156 if (strlcat(buf, " ", size) >= size ||
1157 strlcat(buf, ATTR_NAME(aptr->attr_type)((aptr->attr_type)->names ? (((aptr->attr_type)->
names)->slh_first)->name : (aptr->attr_type)->oid
)
, size) >= size)
1158 return -1;
1159 } else {
1160 if (strlcat(buf, " ( ", size) >= size)
1161 return -1;
1162 SLIST_FOREACH(aptr, alist, next)for((aptr) = ((alist)->slh_first); (aptr) != ((void *)0); (
aptr) = ((aptr)->next.sle_next))
{
1163 if (strlcat(buf, ATTR_NAME(aptr->attr_type)((aptr->attr_type)->names ? (((aptr->attr_type)->
names)->slh_first)->name : (aptr->attr_type)->oid
)
,
1164 size) >= size ||
1165 strlcat(buf, " ", size) >= size)
1166 return -1;
1167 if (SLIST_NEXT(aptr, next)((aptr)->next.sle_next) != NULL((void *)0) &&
1168 strlcat(buf, "$ ", size) >= size)
1169 return -1;
1170 }
1171 if (strlcat(buf, ")", size) >= size)
1172 return -1;
1173 }
1174
1175 return 0;
1176}
1177
1178static int
1179schema_dump_objlist(const char *desc, struct obj_list *olist,
1180 char *buf, size_t size)
1181{
1182 struct obj_ptr *optr;
1183
1184 if (olist == NULL((void *)0) || SLIST_EMPTY(olist)(((olist)->slh_first) == ((void *)0)))
1185 return 0;
1186
1187 if (strlcat(buf, " ", size) >= size ||
1188 strlcat(buf, desc, size) >= size)
1189 return -1;
1190
1191 optr = SLIST_FIRST(olist)((olist)->slh_first);
1192 if (SLIST_NEXT(optr, next)((optr)->next.sle_next) == NULL((void *)0)) {
1193 /* single attribute, no parenthesis */
1194 if (strlcat(buf, " ", size) >= size ||
1195 strlcat(buf, OBJ_NAME(optr->object)((optr->object)->names ? (((optr->object)->names)
->slh_first)->name : (optr->object)->oid)
, size) >= size)
1196 return -1;
1197 } else {
1198 if (strlcat(buf, " ( ", size) >= size)
1199 return -1;
1200 SLIST_FOREACH(optr, olist, next)for((optr) = ((olist)->slh_first); (optr) != ((void *)0); (
optr) = ((optr)->next.sle_next))
{
1201 if (strlcat(buf, OBJ_NAME(optr->object)((optr->object)->names ? (((optr->object)->names)
->slh_first)->name : (optr->object)->oid)
, size) >= size ||
1202 strlcat(buf, " ", size) >= size)
1203 return -1;
1204 if (SLIST_NEXT(optr, next)((optr)->next.sle_next) != NULL((void *)0) &&
1205 strlcat(buf, "$ ", size) >= size)
1206 return -1;
1207 }
1208 if (strlcat(buf, ")", size) >= size)
1209 return -1;
1210 }
1211
1212 return 0;
1213}
1214
1215int
1216schema_dump_object(struct object *obj, char *buf, size_t size)
1217{
1218 if (strlcpy(buf, "( ", size) >= size ||
1219 strlcat(buf, obj->oid, size) >= size)
1220 return -1;
1221
1222 if (schema_dump_names("NAME", obj->names, buf, size) != 0)
1223 return -1;
1224
1225 if (obj->desc != NULL((void *)0))
1226 if (strlcat(buf, " DESC '", size) >= size ||
1227 strlcat(buf, obj->desc, size) >= size ||
1228 strlcat(buf, "'", size) >= size)
1229 return -1;
1230
1231 switch (obj->kind) {
1232 case KIND_STRUCTURAL:
1233 if (strlcat(buf, " STRUCTURAL", size) >= size)
1234 return -1;
1235 break;
1236 case KIND_ABSTRACT:
1237 if (strlcat(buf, " ABSTRACT", size) >= size)
1238 return -1;
1239 break;
1240 case KIND_AUXILIARY:
1241 if (strlcat(buf, " AUXILIARY", size) >= size)
1242 return -1;
1243 break;
1244 }
1245
1246 if (schema_dump_objlist("SUP", obj->sup, buf, size) != 0)
1247 return -1;
1248
1249 if (obj->obsolete && strlcat(buf, " OBSOLETE", size) >= size)
1250 return -1;
1251
1252 if (schema_dump_attrlist("MUST", obj->must, buf, size) != 0)
1253 return -1;
1254
1255 if (schema_dump_attrlist("MAY", obj->may, buf, size) != 0)
1256 return -1;
1257
1258 if (strlcat(buf, " )", size) >= size)
1259 return -1;
1260
1261 return 0;
1262}
1263
1264int
1265schema_dump_attribute(struct attr_type *at, char *buf, size_t size)
1266{
1267 if (strlcpy(buf, "( ", size) >= size ||
1268 strlcat(buf, at->oid, size) >= size)
1269 return -1;
1270
1271 if (schema_dump_names("NAME", at->names, buf, size) != 0)
1272 return -1;
1273
1274 if (at->desc != NULL((void *)0))
1275 if (strlcat(buf, " DESC '", size) >= size ||
1276 strlcat(buf, at->desc, size) >= size ||
1277 strlcat(buf, "'", size) >= size)
1278 return -1;
1279
1280 if (at->obsolete && strlcat(buf, " OBSOLETE", size) >= size)
1281 return -1;
1282
1283 if (at->sup != NULL((void *)0))
1284 if (strlcat(buf, " SUP ", size) >= size ||
1285 strlcat(buf, ATTR_NAME(at->sup)((at->sup)->names ? (((at->sup)->names)->slh_first
)->name : (at->sup)->oid)
, size) >= size)
1286 return -1;
1287
1288 if (at->equality != NULL((void *)0))
1289 if (strlcat(buf, " EQUALITY ", size) >= size ||
1290 strlcat(buf, at->equality->name, size) >= size)
1291 return -1;
1292
1293 if (at->ordering != NULL((void *)0))
1294 if (strlcat(buf, " ORDERING ", size) >= size ||
1295 strlcat(buf, at->ordering->name, size) >= size)
1296 return -1;
1297
1298 if (at->substr != NULL((void *)0))
1299 if (strlcat(buf, " SUBSTR ", size) >= size ||
1300 strlcat(buf, at->substr->name, size) >= size)
1301 return -1;
1302
1303 if (at->syntax != NULL((void *)0))
1304 if (strlcat(buf, " SYNTAX ", size) >= size ||
1305 strlcat(buf, at->syntax->oid, size) >= size)
1306 return -1;
1307
1308 if (at->single && strlcat(buf, " SINGLE-VALUE", size) >= size)
1309 return -1;
1310
1311 if (at->collective && strlcat(buf, " COLLECTIVE", size) >= size)
1312 return -1;
1313
1314 if (at->immutable && strlcat(buf, " NO-USER-MODIFICATION", size) >= size)
1315 return -1;
1316
1317 switch (at->usage) {
1318 case USAGE_USER_APP:
1319 /* User application usage is the default. */
1320 break;
1321 case USAGE_DIR_OP:
1322 if (strlcat(buf, " USAGE directoryOperation", size) >= size)
1323 return -1;
1324 break;
1325 case USAGE_DIST_OP:
1326 if (strlcat(buf, " USAGE distributedOperation", size) >= size)
1327 return -1;
1328 break;
1329 case USAGE_DSA_OP:
1330 if (strlcat(buf, " USAGE dSAOperation", size) >= size)
1331 return -1;
1332 break;
1333 }
1334
1335 if (strlcat(buf, " )", size) >= size)
1336 return -1;
1337
1338 return 0;
1339}
1340
1341int
1342schema_dump_match_rule(struct match_rule *mr, char *buf, size_t size)
1343{
1344 if (strlcpy(buf, "( ", size) >= size ||
1345 strlcat(buf, mr->oid, size) >= size ||
1346 strlcat(buf, " NAME '", size) >= size ||
1347 strlcat(buf, mr->name, size) >= size ||
1348 strlcat(buf, "' SYNTAX ", size) >= size ||
1349 strlcat(buf, mr->syntax_oid, size) >= size ||
1350 strlcat(buf, " )", size) >= size)
1351 return -1;
1352
1353 return 0;
1354}
1355