Bug Summary

File:src/usr.sbin/ldapd/schema.c
Warning:line 41, column 9
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);
38
Null pointer passed as 1st argument to string comparison function
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); }
;
36
Loop condition is true. Entering loop body
37
Calling 'obj_oid_cmp'
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
)
12
Taking true branch
350 *kw = NULL((void *)0);
13
Null pointer value stored to 'kw'
351
352top:
353 p = buf;
354 while ((c = schema_getc(schema, 0)) == ' ' || c == '\t')
14
Assuming the condition is false
15
Assuming the condition is false
16
Loop condition is false. Execution continues on line 357
355 ; /* nothing */
356
357 if (c == '#')
17
Assuming the condition is false
18
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 == '*') {
19
Assuming the character is non-alphanumeric
20
Assuming the condition is false
21
Assuming the condition is false
22
Assuming the condition is false
23
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') {
24
Assuming the condition is false
25
Taking false branch
416 schema->lineno++;
417 goto top;
418 }
419 if (c == EOF(-1))
26
Assuming the condition is false
27
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'
28
Returning from 'schema_lex'
29
Assuming the condition is false
30
Taking false branch
907 goto fail;
908
909 if ((obj = calloc(1, sizeof(*obj))) == NULL((void *)0)) {
31
Assuming the condition is false
32
Taking false branch
910 log_warn("calloc");
911 goto fail;
912 }
913 obj->kind = KIND_STRUCTURAL;
914
915 if (is_oidstr(kw))
33
Taking true branch
916 obj->oid = kw;
34
Null pointer value stored to field 'oid'
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);
35
Calling 'object_tree_RB_INSERT'
926 if (prev != NULL((void *)0)) {
927 schema_err(schema, "object class %s already defined", obj->oid);
928 goto fail;
929 }
930
931 while (ret == 0) {
932 token = schema_lex(schema, &kw);
933 if (token == ')')
934 break;
935 else if (token != STRING1)
936 goto fail;
937 if (strcasecmp(kw, "NAME") == 0) {
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