| File: | src/usr.sbin/snmpd/application_agentx.c |
| Warning: | line 262, column 4 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: application_agentx.c,v 1.15 2023/12/21 12:43:30 martijn Exp $ */ | |||
| 2 | /* | |||
| 3 | * Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org> | |||
| 4 | * | |||
| 5 | * Permission to use, copy, modify, and distribute this software for any | |||
| 6 | * purpose with or without fee is hereby granted, provided that the above | |||
| 7 | * copyright notice and this permission notice appear in all copies. | |||
| 8 | * | |||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| 16 | */ | |||
| 17 | ||||
| 18 | #include <sys/queue.h> | |||
| 19 | #include <sys/socket.h> | |||
| 20 | #include <sys/stat.h> | |||
| 21 | #include <sys/tree.h> | |||
| 22 | #include <sys/un.h> | |||
| 23 | ||||
| 24 | #include <ber.h> | |||
| 25 | #include <errno(*__errno()).h> | |||
| 26 | #include <event.h> | |||
| 27 | #include <inttypes.h> | |||
| 28 | #include <stdint.h> | |||
| 29 | #include <stdio.h> | |||
| 30 | #include <stdlib.h> | |||
| 31 | #include <string.h> | |||
| 32 | #include <unistd.h> | |||
| 33 | ||||
| 34 | #include "application.h" | |||
| 35 | #include "ax.h" | |||
| 36 | #include "log.h" | |||
| 37 | #include "smi.h" | |||
| 38 | #include "snmp.h" | |||
| 39 | #include "snmpd.h" | |||
| 40 | ||||
| 41 | #define AGENTX_DEFAULTTIMEOUT5 5 | |||
| 42 | ||||
| 43 | struct appl_agentx_connection { | |||
| 44 | uint32_t conn_id; | |||
| 45 | /* | |||
| 46 | * A backend has several overruling properties: | |||
| 47 | * - If it exits, snmpd crashes | |||
| 48 | * - All registrations are priority 1 | |||
| 49 | * - All registrations own the subtree. | |||
| 50 | */ | |||
| 51 | int conn_backend; | |||
| 52 | struct ax *conn_ax; | |||
| 53 | struct event conn_rev; | |||
| 54 | struct event conn_wev; | |||
| 55 | ||||
| 56 | TAILQ_HEAD(, appl_agentx_session)struct { struct appl_agentx_session *tqh_first; struct appl_agentx_session **tqh_last; } conn_sessions; | |||
| 57 | RB_ENTRY(appl_agentx_connection)struct { struct appl_agentx_connection *rbe_left; struct appl_agentx_connection *rbe_right; struct appl_agentx_connection *rbe_parent; int rbe_color ; } conn_entry; | |||
| 58 | }; | |||
| 59 | ||||
| 60 | struct appl_agentx_session { | |||
| 61 | uint32_t sess_id; | |||
| 62 | struct appl_agentx_connection *sess_conn; | |||
| 63 | /* | |||
| 64 | * RFC 2741 section 7.1.1: | |||
| 65 | * All subsequent AgentX protocol operations initiated by the master | |||
| 66 | * agent for this session must use this byte ordering and set this bit | |||
| 67 | * accordingly. | |||
| 68 | */ | |||
| 69 | enum ax_byte_order sess_byteorder; | |||
| 70 | uint8_t sess_timeout; | |||
| 71 | struct ax_oid sess_oid; | |||
| 72 | struct ax_ostring sess_descr; | |||
| 73 | struct appl_backend sess_backend; | |||
| 74 | ||||
| 75 | RB_ENTRY(appl_agentx_session)struct { struct appl_agentx_session *rbe_left; struct appl_agentx_session *rbe_right; struct appl_agentx_session *rbe_parent; int rbe_color ; } sess_entry; | |||
| 76 | TAILQ_ENTRY(appl_agentx_session)struct { struct appl_agentx_session *tqe_next; struct appl_agentx_session **tqe_prev; } sess_conn_entry; | |||
| 77 | }; | |||
| 78 | ||||
| 79 | void appl_agentx_listen(struct agentx_master *); | |||
| 80 | void appl_agentx_accept(int, short, void *); | |||
| 81 | void appl_agentx_free(struct appl_agentx_connection *, enum appl_close_reason); | |||
| 82 | void appl_agentx_recv(int, short, void *); | |||
| 83 | void appl_agentx_open(struct appl_agentx_connection *, struct ax_pdu *); | |||
| 84 | void appl_agentx_close(struct appl_agentx_session *, struct ax_pdu *); | |||
| 85 | void appl_agentx_forceclose(struct appl_backend *, enum appl_close_reason); | |||
| 86 | void appl_agentx_session_free(struct appl_agentx_session *); | |||
| 87 | void appl_agentx_register(struct appl_agentx_session *, struct ax_pdu *); | |||
| 88 | void appl_agentx_unregister(struct appl_agentx_session *, struct ax_pdu *); | |||
| 89 | void appl_agentx_get(struct appl_backend *, int32_t, int32_t, const char *, | |||
| 90 | struct appl_varbind *); | |||
| 91 | void appl_agentx_getnext(struct appl_backend *, int32_t, int32_t, const char *, | |||
| 92 | struct appl_varbind *); | |||
| 93 | void appl_agentx_addagentcaps(struct appl_agentx_session *, struct ax_pdu *); | |||
| 94 | void appl_agentx_removeagentcaps(struct appl_agentx_session *, struct ax_pdu *); | |||
| 95 | void appl_agentx_response(struct appl_agentx_session *, struct ax_pdu *); | |||
| 96 | void appl_agentx_send(int, short, void *); | |||
| 97 | struct ber_oid *appl_agentx_oid2ber_oid(struct ax_oid *, struct ber_oid *); | |||
| 98 | struct ber_element *appl_agentx_value2ber_element(struct ax_varbind *); | |||
| 99 | struct ax_ostring *appl_agentx_string2ostring(const char *, | |||
| 100 | struct ax_ostring *); | |||
| 101 | int appl_agentx_cmp(struct appl_agentx_connection *, | |||
| 102 | struct appl_agentx_connection *); | |||
| 103 | int appl_agentx_session_cmp(struct appl_agentx_session *, | |||
| 104 | struct appl_agentx_session *); | |||
| 105 | ||||
| 106 | struct appl_backend_functions appl_agentx_functions = { | |||
| 107 | .ab_close = appl_agentx_forceclose, | |||
| 108 | .ab_get = appl_agentx_get, | |||
| 109 | .ab_getnext = appl_agentx_getnext, | |||
| 110 | .ab_getbulk = NULL((void *)0), /* not properly supported in application.c and libagentx */ | |||
| 111 | }; | |||
| 112 | ||||
| 113 | RB_HEAD(appl_agentx_conns, appl_agentx_connection)struct appl_agentx_conns { struct appl_agentx_connection *rbh_root ; } appl_agentx_conns = | |||
| 114 | RB_INITIALIZER(&appl_agentx_conns){ ((void *)0) }; | |||
| 115 | RB_HEAD(appl_agentx_sessions, appl_agentx_session)struct appl_agentx_sessions { struct appl_agentx_session *rbh_root ; } appl_agentx_sessions = | |||
| 116 | RB_INITIALIZER(&appl_agentx_sessions){ ((void *)0) }; | |||
| 117 | ||||
| 118 | RB_PROTOTYPE_STATIC(appl_agentx_conns, appl_agentx_connection, conn_entry,__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR (struct appl_agentx_conns *, struct appl_agentx_connection *) ; __attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR (struct appl_agentx_conns *, struct appl_agentx_connection *, struct appl_agentx_connection *);__attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_REMOVE (struct appl_agentx_conns *, struct appl_agentx_connection *) ; __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_INSERT(struct appl_agentx_conns *, struct appl_agentx_connection *); __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_FIND(struct appl_agentx_conns *, struct appl_agentx_connection *); __attribute__ ((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_NFIND (struct appl_agentx_conns *, struct appl_agentx_connection *) ; __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_NEXT(struct appl_agentx_connection *); __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_PREV(struct appl_agentx_connection *); __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_MINMAX(struct appl_agentx_conns *, int ); | |||
| 119 | appl_agentx_cmp)__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR (struct appl_agentx_conns *, struct appl_agentx_connection *) ; __attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR (struct appl_agentx_conns *, struct appl_agentx_connection *, struct appl_agentx_connection *);__attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_REMOVE (struct appl_agentx_conns *, struct appl_agentx_connection *) ; __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_INSERT(struct appl_agentx_conns *, struct appl_agentx_connection *); __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_FIND(struct appl_agentx_conns *, struct appl_agentx_connection *); __attribute__ ((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_NFIND (struct appl_agentx_conns *, struct appl_agentx_connection *) ; __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_NEXT(struct appl_agentx_connection *); __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_PREV(struct appl_agentx_connection *); __attribute__((__unused__)) static struct appl_agentx_connection *appl_agentx_conns_RB_MINMAX(struct appl_agentx_conns *, int );; | |||
| 120 | RB_PROTOTYPE_STATIC(appl_agentx_sessions, appl_agentx_session, sess_entry,__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR (struct appl_agentx_sessions *, struct appl_agentx_session *) ; __attribute__((__unused__)) static void appl_agentx_sessions_RB_REMOVE_COLOR (struct appl_agentx_sessions *, struct appl_agentx_session *, struct appl_agentx_session *);__attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_REMOVE(struct appl_agentx_sessions *, struct appl_agentx_session *); __attribute__ ((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_INSERT (struct appl_agentx_sessions *, struct appl_agentx_session *) ; __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_FIND(struct appl_agentx_sessions *, struct appl_agentx_session *); __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_NFIND(struct appl_agentx_sessions *, struct appl_agentx_session *); __attribute__ ((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_NEXT (struct appl_agentx_session *); __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_PREV(struct appl_agentx_session *); __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_MINMAX(struct appl_agentx_sessions *, int); | |||
| 121 | appl_agentx_session_cmp)__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR (struct appl_agentx_sessions *, struct appl_agentx_session *) ; __attribute__((__unused__)) static void appl_agentx_sessions_RB_REMOVE_COLOR (struct appl_agentx_sessions *, struct appl_agentx_session *, struct appl_agentx_session *);__attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_REMOVE(struct appl_agentx_sessions *, struct appl_agentx_session *); __attribute__ ((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_INSERT (struct appl_agentx_sessions *, struct appl_agentx_session *) ; __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_FIND(struct appl_agentx_sessions *, struct appl_agentx_session *); __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_NFIND(struct appl_agentx_sessions *, struct appl_agentx_session *); __attribute__ ((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_NEXT (struct appl_agentx_session *); __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_PREV(struct appl_agentx_session *); __attribute__((__unused__)) static struct appl_agentx_session *appl_agentx_sessions_RB_MINMAX(struct appl_agentx_sessions *, int);; | |||
| 122 | ||||
| 123 | void | |||
| 124 | appl_agentx(void) | |||
| 125 | { | |||
| 126 | struct agentx_master *master; | |||
| 127 | ||||
| 128 | TAILQ_FOREACH(master, &(snmpd_env->sc_agentx_masters), axm_entry)for((master) = ((&(snmpd_env->sc_agentx_masters))-> tqh_first); (master) != ((void *)0); (master) = ((master)-> axm_entry.tqe_next)) | |||
| 129 | appl_agentx_listen(master); | |||
| 130 | } | |||
| 131 | ||||
| 132 | void | |||
| 133 | appl_agentx_init(void) | |||
| 134 | { | |||
| 135 | struct agentx_master *master; | |||
| 136 | ||||
| 137 | TAILQ_FOREACH(master, &(snmpd_env->sc_agentx_masters), axm_entry)for((master) = ((&(snmpd_env->sc_agentx_masters))-> tqh_first); (master) != ((void *)0); (master) = ((master)-> axm_entry.tqe_next)) { | |||
| 138 | if (master->axm_fd == -1) | |||
| 139 | continue; | |||
| 140 | event_set(&(master->axm_ev), master->axm_fd, | |||
| 141 | EV_READ0x02 | EV_PERSIST0x10, appl_agentx_accept, master); | |||
| 142 | event_add(&(master->axm_ev), NULL((void *)0)); | |||
| 143 | log_info("AgentX: listening on %s", master->axm_sun.sun_path); | |||
| 144 | } | |||
| 145 | } | |||
| 146 | void | |||
| 147 | appl_agentx_listen(struct agentx_master *master) | |||
| 148 | { | |||
| 149 | mode_t mask; | |||
| 150 | ||||
| 151 | unlink(master->axm_sun.sun_path); | |||
| 152 | ||||
| 153 | mask = umask(0777); | |||
| 154 | if ((master->axm_fd = socket(AF_UNIX1, SOCK_STREAM1, 0)) == -1 || | |||
| 155 | bind(master->axm_fd, (struct sockaddr *)&(master->axm_sun), | |||
| 156 | sizeof(master->axm_sun)) == -1 || | |||
| 157 | listen(master->axm_fd, 5)) { | |||
| 158 | log_warn("AgentX: listen %s", master->axm_sun.sun_path); | |||
| 159 | umask(mask); | |||
| 160 | return; | |||
| 161 | } | |||
| 162 | umask(mask); | |||
| 163 | if (chown(master->axm_sun.sun_path, master->axm_owner, | |||
| 164 | master->axm_group) == -1) { | |||
| 165 | log_warn("AgentX: chown %s", master->axm_sun.sun_path); | |||
| 166 | goto fail; | |||
| 167 | } | |||
| 168 | if (chmod(master->axm_sun.sun_path, master->axm_mode) == -1) { | |||
| 169 | log_warn("AgentX: chmod %s", master->axm_sun.sun_path); | |||
| 170 | goto fail; | |||
| 171 | } | |||
| 172 | return; | |||
| 173 | fail: | |||
| 174 | close(master->axm_fd); | |||
| 175 | master->axm_fd = -1; | |||
| 176 | } | |||
| 177 | ||||
| 178 | void | |||
| 179 | appl_agentx_shutdown(void) | |||
| 180 | { | |||
| 181 | struct appl_agentx_connection *conn, *tconn; | |||
| 182 | ||||
| 183 | RB_FOREACH_SAFE(conn, appl_agentx_conns, &appl_agentx_conns, tconn)for ((conn) = appl_agentx_conns_RB_MINMAX(&appl_agentx_conns , -1); ((conn) != ((void *)0)) && ((tconn) = appl_agentx_conns_RB_NEXT (conn), 1); (conn) = (tconn)) | |||
| ||||
| 184 | appl_agentx_free(conn, APPL_CLOSE_REASONSHUTDOWN); | |||
| 185 | } | |||
| 186 | ||||
| 187 | void | |||
| 188 | appl_agentx_accept(int masterfd, short event, void *cookie) | |||
| 189 | { | |||
| 190 | int fd; | |||
| 191 | struct agentx_master *master = cookie; | |||
| 192 | struct sockaddr_un sun; | |||
| 193 | socklen_t sunlen = sizeof(sun); | |||
| 194 | struct appl_agentx_connection *conn = NULL((void *)0); | |||
| 195 | ||||
| 196 | if ((fd = accept(masterfd, (struct sockaddr *)&sun, &sunlen)) == -1) { | |||
| 197 | log_warn("AgentX: accept %s", master->axm_sun.sun_path); | |||
| 198 | return; | |||
| 199 | } | |||
| 200 | ||||
| 201 | if ((conn = malloc(sizeof(*conn))) == NULL((void *)0)) { | |||
| 202 | log_warn(NULL((void *)0)); | |||
| 203 | goto fail; | |||
| 204 | } | |||
| 205 | ||||
| 206 | conn->conn_backend = 0; | |||
| 207 | TAILQ_INIT(&(conn->conn_sessions))do { (&(conn->conn_sessions))->tqh_first = ((void * )0); (&(conn->conn_sessions))->tqh_last = &(& (conn->conn_sessions))->tqh_first; } while (0); | |||
| 208 | if ((conn->conn_ax = ax_new(fd)) == NULL((void *)0)) { | |||
| 209 | log_warn(NULL((void *)0)); | |||
| 210 | goto fail; | |||
| 211 | } | |||
| 212 | ||||
| 213 | do { | |||
| 214 | conn->conn_id = arc4random(); | |||
| 215 | } while (RB_INSERT(appl_agentx_conns,appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn) | |||
| 216 | &appl_agentx_conns, conn)appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn) != NULL((void *)0)); | |||
| 217 | ||||
| 218 | event_set(&(conn->conn_rev), fd, EV_READ0x02 | EV_PERSIST0x10, | |||
| 219 | appl_agentx_recv, conn); | |||
| 220 | event_add(&(conn->conn_rev), NULL((void *)0)); | |||
| 221 | event_set(&(conn->conn_wev), fd, EV_WRITE0x04, appl_agentx_send, conn); | |||
| 222 | log_info("AgentX(%"PRIu32"u""): new connection", conn->conn_id); | |||
| 223 | ||||
| 224 | return; | |||
| 225 | fail: | |||
| 226 | close(fd); | |||
| 227 | free(conn); | |||
| 228 | } | |||
| 229 | ||||
| 230 | void | |||
| 231 | appl_agentx_backend(int fd) | |||
| 232 | { | |||
| 233 | struct appl_agentx_connection *conn; | |||
| 234 | ||||
| 235 | if ((conn = malloc(sizeof(*conn))) == NULL((void *)0)) | |||
| 236 | fatal(NULL((void *)0)); | |||
| 237 | ||||
| 238 | conn->conn_backend = 1; | |||
| 239 | TAILQ_INIT(&(conn->conn_sessions))do { (&(conn->conn_sessions))->tqh_first = ((void * )0); (&(conn->conn_sessions))->tqh_last = &(& (conn->conn_sessions))->tqh_first; } while (0); | |||
| 240 | if ((conn->conn_ax = ax_new(fd)) == NULL((void *)0)) | |||
| 241 | fatal("ax_new"); | |||
| 242 | ||||
| 243 | do { | |||
| 244 | conn->conn_id = arc4random(); | |||
| 245 | } while (RB_INSERT(appl_agentx_conns,appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn) | |||
| 246 | &appl_agentx_conns, conn)appl_agentx_conns_RB_INSERT(&appl_agentx_conns, conn) != NULL((void *)0)); | |||
| 247 | ||||
| 248 | event_set(&(conn->conn_rev), fd, EV_READ0x02 | EV_PERSIST0x10, | |||
| 249 | appl_agentx_recv, conn); | |||
| 250 | event_add(&(conn->conn_rev), NULL((void *)0)); | |||
| 251 | event_set(&(conn->conn_wev), fd, EV_WRITE0x04, appl_agentx_send, conn); | |||
| 252 | } | |||
| 253 | ||||
| 254 | void | |||
| 255 | appl_agentx_free(struct appl_agentx_connection *conn, | |||
| 256 | enum appl_close_reason reason) | |||
| 257 | { | |||
| 258 | struct appl_agentx_session *session; | |||
| 259 | ||||
| 260 | while ((session = TAILQ_FIRST(&(conn->conn_sessions))((&(conn->conn_sessions))->tqh_first)) != NULL((void *)0)) { | |||
| 261 | if (conn->conn_ax
| |||
| 262 | appl_agentx_session_free(session); | |||
| ||||
| 263 | else | |||
| 264 | appl_agentx_forceclose(&(session->sess_backend), | |||
| 265 | reason); | |||
| 266 | } | |||
| 267 | ||||
| 268 | event_del(&(conn->conn_rev)); | |||
| 269 | event_del(&(conn->conn_wev)); | |||
| 270 | ||||
| 271 | RB_REMOVE(appl_agentx_conns, &appl_agentx_conns, conn)appl_agentx_conns_RB_REMOVE(&appl_agentx_conns, conn); | |||
| 272 | if (conn->conn_ax != NULL((void *)0)) | |||
| 273 | (void)ax_send(conn->conn_ax); | |||
| 274 | ax_free(conn->conn_ax); | |||
| 275 | if (conn->conn_backend) | |||
| 276 | fatalx("AgentX(%"PRIu32"u""): disappeared unexpected", | |||
| 277 | conn->conn_id); | |||
| 278 | free(conn); | |||
| 279 | } | |||
| 280 | ||||
| 281 | void | |||
| 282 | appl_agentx_recv(int fd, short event, void *cookie) | |||
| 283 | { | |||
| 284 | struct appl_agentx_connection *conn = cookie; | |||
| 285 | struct appl_agentx_session *session = NULL((void *)0); | |||
| 286 | struct ax_pdu *pdu; | |||
| 287 | enum appl_error error; | |||
| 288 | char name[100]; | |||
| 289 | ||||
| 290 | snprintf(name, sizeof(name), "AgentX(%"PRIu32"u"")", conn->conn_id); | |||
| 291 | if ((pdu = ax_recv(conn->conn_ax)) == NULL((void *)0)) { | |||
| 292 | if (errno(*__errno()) == EAGAIN35) | |||
| 293 | return; | |||
| 294 | log_warn("%s", name); | |||
| 295 | /* | |||
| 296 | * Either the connection is dead, or we had garbage on the line. | |||
| 297 | * Both make sure we can't continue on this stream. | |||
| 298 | */ | |||
| 299 | if (errno(*__errno()) == ECONNRESET54) { | |||
| 300 | ax_free(conn->conn_ax); | |||
| 301 | conn->conn_ax = NULL((void *)0); | |||
| 302 | } | |||
| 303 | appl_agentx_free(conn, errno(*__errno()) == EPROTO95 ? | |||
| 304 | APPL_CLOSE_REASONPROTOCOLERROR : APPL_CLOSE_REASONOTHER); | |||
| 305 | return; | |||
| 306 | } | |||
| 307 | ||||
| 308 | conn->conn_ax->ax_byteorder = pdu->ap_header.aph_flags & | |||
| 309 | AX_PDU_FLAG_NETWORK_BYTE_ORDER(1 << 4) ? | |||
| 310 | AX_BYTE_ORDER_BE : AX_BYTE_ORDER_LE; | |||
| 311 | if (pdu->ap_header.aph_type != AX_PDU_TYPE_OPEN) { | |||
| 312 | /* Make sure we only look for connection-local sessions */ | |||
| 313 | TAILQ_FOREACH(session, &(conn->conn_sessions),for((session) = ((&(conn->conn_sessions))->tqh_first ); (session) != ((void *)0); (session) = ((session)->sess_conn_entry .tqe_next)) | |||
| 314 | sess_conn_entry)for((session) = ((&(conn->conn_sessions))->tqh_first ); (session) != ((void *)0); (session) = ((session)->sess_conn_entry .tqe_next)) { | |||
| 315 | if (session->sess_id == pdu->ap_header.aph_sessionid) | |||
| 316 | break; | |||
| 317 | } | |||
| 318 | if (session == NULL((void *)0)) { | |||
| 319 | log_warnx("%s: Session %"PRIu32"u"" not found for request", | |||
| 320 | name, pdu->ap_header.aph_sessionid); | |||
| 321 | error = APPL_ERROR_NOTOPEN; | |||
| 322 | goto fail; | |||
| 323 | } | |||
| 324 | strlcpy(name, session->sess_backend.ab_name, sizeof(name)); | |||
| 325 | /* | |||
| 326 | * RFC2741 section 7.1.1 bullet 4 is unclear on what byte order | |||
| 327 | * the response should be. My best guess is that it makes more | |||
| 328 | * sense that replies are in the same byte-order as what was | |||
| 329 | * requested. | |||
| 330 | * In practice we always have the same byte order as when we | |||
| 331 | * opened the session, so it's likely a non-issue, however, we | |||
| 332 | * can change to session byte order here. | |||
| 333 | */ | |||
| 334 | } | |||
| 335 | ||||
| 336 | if (pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION(1 << 0)) { | |||
| 337 | if (pdu->ap_header.aph_type != AX_PDU_TYPE_REGISTER) { | |||
| 338 | log_warnx("%s: %s: Invalid INSTANCE_REGISTRATION flag", | |||
| 339 | name, ax_pdutype2string(pdu->ap_header.aph_flags)); | |||
| 340 | error = APPL_ERROR_PARSEERROR; | |||
| 341 | goto fail; | |||
| 342 | } | |||
| 343 | } | |||
| 344 | if (pdu->ap_header.aph_flags & AX_PDU_FLAG_NEW_INDEX(1 << 1)) { | |||
| 345 | if (pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXALLOCATE && | |||
| 346 | pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXDEALLOCATE) { | |||
| 347 | log_warnx("%s: %s: Invalid NEW_INDEX flag", name, | |||
| 348 | ax_pdutype2string(pdu->ap_header.aph_flags)); | |||
| 349 | error = APPL_ERROR_PARSEERROR; | |||
| 350 | goto fail; | |||
| 351 | } | |||
| 352 | } | |||
| 353 | if (pdu->ap_header.aph_flags & AX_PDU_FLAG_ANY_INDEX(1 << 2)) { | |||
| 354 | if (pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXALLOCATE && | |||
| 355 | pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXDEALLOCATE) { | |||
| 356 | log_warnx("%s: %s: Invalid ANY_INDEX flag", name, | |||
| 357 | ax_pdutype2string(pdu->ap_header.aph_flags)); | |||
| 358 | error = APPL_ERROR_PARSEERROR; | |||
| 359 | goto fail; | |||
| 360 | } | |||
| 361 | } | |||
| 362 | if (pdu->ap_header.aph_flags & AX_PDU_FLAG_NON_DEFAULT_CONTEXT(1 << 3)) { | |||
| 363 | if (pdu->ap_header.aph_type != AX_PDU_TYPE_REGISTER && | |||
| 364 | pdu->ap_header.aph_type != AX_PDU_TYPE_UNREGISTER && | |||
| 365 | pdu->ap_header.aph_type != AX_PDU_TYPE_ADDAGENTCAPS && | |||
| 366 | pdu->ap_header.aph_type != AX_PDU_TYPE_REMOVEAGENTCAPS && | |||
| 367 | pdu->ap_header.aph_type != AX_PDU_TYPE_GET && | |||
| 368 | pdu->ap_header.aph_type != AX_PDU_TYPE_GETNEXT && | |||
| 369 | pdu->ap_header.aph_type != AX_PDU_TYPE_GETBULK && | |||
| 370 | pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXALLOCATE && | |||
| 371 | pdu->ap_header.aph_type != AX_PDU_TYPE_INDEXDEALLOCATE && | |||
| 372 | pdu->ap_header.aph_type != AX_PDU_TYPE_NOTIFY && | |||
| 373 | pdu->ap_header.aph_type != AX_PDU_TYPE_TESTSET && | |||
| 374 | pdu->ap_header.aph_type != AX_PDU_TYPE_PING) { | |||
| 375 | log_warnx("%s: %s: Invalid NON_DEFAULT_CONTEXT flag", | |||
| 376 | name, ax_pdutype2string(pdu->ap_header.aph_flags)); | |||
| 377 | error = APPL_ERROR_PARSEERROR; | |||
| 378 | goto fail; | |||
| 379 | } | |||
| 380 | if (appl_context(pdu->ap_context.aos_string, 0) == NULL((void *)0)) { | |||
| 381 | log_warnx("%s: %s: Unsupported context", | |||
| 382 | name, ax_pdutype2string(pdu->ap_header.aph_flags)); | |||
| 383 | error = APPL_ERROR_UNSUPPORTEDCONTEXT; | |||
| 384 | goto fail; | |||
| 385 | } | |||
| 386 | } | |||
| 387 | switch (pdu->ap_header.aph_type) { | |||
| 388 | case AX_PDU_TYPE_OPEN: | |||
| 389 | appl_agentx_open(conn, pdu); | |||
| 390 | break; | |||
| 391 | case AX_PDU_TYPE_CLOSE: | |||
| 392 | appl_agentx_close(session, pdu); | |||
| 393 | break; | |||
| 394 | case AX_PDU_TYPE_REGISTER: | |||
| 395 | appl_agentx_register(session, pdu); | |||
| 396 | break; | |||
| 397 | case AX_PDU_TYPE_UNREGISTER: | |||
| 398 | appl_agentx_unregister(session, pdu); | |||
| 399 | break; | |||
| 400 | case AX_PDU_TYPE_GET: | |||
| 401 | case AX_PDU_TYPE_GETNEXT: | |||
| 402 | case AX_PDU_TYPE_GETBULK: | |||
| 403 | case AX_PDU_TYPE_TESTSET: | |||
| 404 | case AX_PDU_TYPE_COMMITSET: | |||
| 405 | case AX_PDU_TYPE_UNDOSET: | |||
| 406 | case AX_PDU_TYPE_CLEANUPSET: | |||
| 407 | log_warnx("%s: %s: Not an adminsitrative message", name, | |||
| 408 | ax_pdutype2string(pdu->ap_header.aph_type)); | |||
| 409 | error = APPL_ERROR_PARSEERROR; | |||
| 410 | goto fail; | |||
| 411 | case AX_PDU_TYPE_NOTIFY: | |||
| 412 | log_warnx("%s: %s: not supported", name, | |||
| 413 | ax_pdutype2string(pdu->ap_header.aph_type)); | |||
| 414 | /* | |||
| 415 | * RFC 2741 section 7.1.10: | |||
| 416 | * Note that the master agent's successful response indicates | |||
| 417 | * the agentx-Notify-PDU was received and validated. It does | |||
| 418 | * not indicate that any particular notifications were actually | |||
| 419 | * generated or received by notification targets | |||
| 420 | */ | |||
| 421 | /* XXX Not yet - FALLTHROUGH */ | |||
| 422 | case AX_PDU_TYPE_PING: | |||
| 423 | ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid, | |||
| 424 | pdu->ap_header.aph_transactionid, | |||
| 425 | pdu->ap_header.aph_packetid, smi_getticks(), | |||
| 426 | APPL_ERROR_NOERROR, 0, NULL((void *)0), 0); | |||
| 427 | event_add(&(conn->conn_wev), NULL((void *)0)); | |||
| 428 | break; | |||
| 429 | case AX_PDU_TYPE_INDEXALLOCATE: | |||
| 430 | case AX_PDU_TYPE_INDEXDEALLOCATE: | |||
| 431 | log_warnx("%s: %s: not supported", name, | |||
| 432 | ax_pdutype2string(pdu->ap_header.aph_type)); | |||
| 433 | ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid, | |||
| 434 | pdu->ap_header.aph_transactionid, | |||
| 435 | pdu->ap_header.aph_packetid, smi_getticks(), | |||
| 436 | APPL_ERROR_PROCESSINGERROR, 1, | |||
| 437 | pdu->ap_payload.ap_vbl.ap_varbind, | |||
| 438 | pdu->ap_payload.ap_vbl.ap_nvarbind); | |||
| 439 | event_add(&(conn->conn_wev), NULL((void *)0)); | |||
| 440 | break; | |||
| 441 | case AX_PDU_TYPE_ADDAGENTCAPS: | |||
| 442 | appl_agentx_addagentcaps(session, pdu); | |||
| 443 | break; | |||
| 444 | case AX_PDU_TYPE_REMOVEAGENTCAPS: | |||
| 445 | appl_agentx_removeagentcaps(session, pdu); | |||
| 446 | break; | |||
| 447 | case AX_PDU_TYPE_RESPONSE: | |||
| 448 | appl_agentx_response(session, pdu); | |||
| 449 | break; | |||
| 450 | } | |||
| 451 | ||||
| 452 | ax_pdu_free(pdu); | |||
| 453 | return; | |||
| 454 | fail: | |||
| 455 | ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid, | |||
| 456 | pdu->ap_header.aph_transactionid, | |||
| 457 | pdu->ap_header.aph_packetid, smi_getticks(), | |||
| 458 | error, 0, NULL((void *)0), 0); | |||
| 459 | event_add(&(conn->conn_wev), NULL((void *)0)); | |||
| 460 | ax_pdu_free(pdu); | |||
| 461 | ||||
| 462 | if (session == NULL((void *)0) || error != APPL_ERROR_PARSEERROR) | |||
| 463 | return; | |||
| 464 | ||||
| 465 | appl_agentx_forceclose(&(session->sess_backend), | |||
| 466 | APPL_CLOSE_REASONPARSEERROR); | |||
| 467 | if (TAILQ_EMPTY(&(conn->conn_sessions))(((&(conn->conn_sessions))->tqh_first) == ((void *) 0))) | |||
| 468 | appl_agentx_free(conn, APPL_CLOSE_REASONOTHER); | |||
| 469 | } | |||
| 470 | ||||
| 471 | void | |||
| 472 | appl_agentx_open(struct appl_agentx_connection *conn, struct ax_pdu *pdu) | |||
| 473 | { | |||
| 474 | struct appl_agentx_session *session; | |||
| 475 | struct ber_oid oid; | |||
| 476 | char oidbuf[1024]; | |||
| 477 | enum appl_error error = APPL_ERROR_NOERROR; | |||
| 478 | ||||
| 479 | if ((session = malloc(sizeof(*session))) == NULL((void *)0)) { | |||
| 480 | log_warn(NULL((void *)0)); | |||
| 481 | error = APPL_ERROR_OPENFAILED; | |||
| 482 | goto fail; | |||
| 483 | } | |||
| 484 | session->sess_descr.aos_string = NULL((void *)0); | |||
| 485 | ||||
| 486 | session->sess_conn = conn; | |||
| 487 | if (pdu->ap_header.aph_flags & AX_PDU_FLAG_NETWORK_BYTE_ORDER(1 << 4)) | |||
| 488 | session->sess_byteorder = AX_BYTE_ORDER_BE; | |||
| 489 | else | |||
| 490 | session->sess_byteorder = AX_BYTE_ORDER_LE; | |||
| 491 | ||||
| 492 | /* RFC 2742 agentxSessionObjectID */ | |||
| 493 | if (pdu->ap_payload.ap_open.ap_oid.aoi_idlen == 0) { | |||
| 494 | pdu->ap_payload.ap_open.ap_oid.aoi_id[0] = 0; | |||
| 495 | pdu->ap_payload.ap_open.ap_oid.aoi_id[1] = 0; | |||
| 496 | pdu->ap_payload.ap_open.ap_oid.aoi_idlen = 2; | |||
| 497 | } else if (pdu->ap_payload.ap_open.ap_oid.aoi_idlen == 1) { | |||
| 498 | log_warnx("AgentX(%"PRIu32"u""): Invalid oid: Open Failed", | |||
| 499 | conn->conn_id); | |||
| 500 | error = APPL_ERROR_PARSEERROR; | |||
| 501 | goto fail; | |||
| 502 | } | |||
| 503 | /* RFC 2742 agentxSessionDescr */ | |||
| 504 | if (pdu->ap_payload.ap_open.ap_descr.aos_slen > 255) { | |||
| 505 | log_warnx("AgentX(%"PRIu32"u""): Invalid descr (too long): Open " | |||
| 506 | "Failed", conn->conn_id); | |||
| 507 | error = APPL_ERROR_PARSEERROR; | |||
| 508 | goto fail; | |||
| 509 | } | |||
| 510 | /* | |||
| 511 | * ax_ostring is always NUL-terminated, but doesn't scan for internal | |||
| 512 | * NUL-bytes. However, mbstowcs stops at NUL, which might be in the | |||
| 513 | * middle of the string. | |||
| 514 | */ | |||
| 515 | if (strlen(pdu->ap_payload.ap_open.ap_descr.aos_string) != | |||
| 516 | pdu->ap_payload.ap_open.ap_descr.aos_slen || | |||
| 517 | mbstowcs(NULL((void *)0), | |||
| 518 | pdu->ap_payload.ap_open.ap_descr.aos_string, 0) == (size_t)-1) { | |||
| 519 | log_warnx("AgentX(%"PRIu32"u""): Invalid descr (not UTF-8): " | |||
| 520 | "Open Failed", conn->conn_id); | |||
| 521 | error = APPL_ERROR_PARSEERROR; | |||
| 522 | goto fail; | |||
| 523 | } | |||
| 524 | ||||
| 525 | session->sess_timeout = pdu->ap_payload.ap_open.ap_timeout; | |||
| 526 | session->sess_oid = pdu->ap_payload.ap_open.ap_oid; | |||
| 527 | session->sess_descr.aos_slen = pdu->ap_payload.ap_open.ap_descr.aos_slen; | |||
| 528 | if (pdu->ap_payload.ap_open.ap_descr.aos_string != NULL((void *)0)) { | |||
| 529 | session->sess_descr.aos_string = | |||
| 530 | strdup(pdu->ap_payload.ap_open.ap_descr.aos_string); | |||
| 531 | if (session->sess_descr.aos_string == NULL((void *)0)) { | |||
| 532 | log_warn("AgentX(%"PRIu32"u""): strdup: Open Failed", | |||
| 533 | conn->conn_id); | |||
| 534 | error = APPL_ERROR_OPENFAILED; | |||
| 535 | goto fail; | |||
| 536 | } | |||
| 537 | } | |||
| 538 | ||||
| 539 | /* RFC 2742 agentxSessionIndex: chances of reuse, slim to none */ | |||
| 540 | do { | |||
| 541 | session->sess_id = arc4random(); | |||
| 542 | } while (RB_INSERT(appl_agentx_sessions,appl_agentx_sessions_RB_INSERT(&appl_agentx_sessions, session ) | |||
| 543 | &appl_agentx_sessions, session)appl_agentx_sessions_RB_INSERT(&appl_agentx_sessions, session ) != NULL((void *)0)); | |||
| 544 | ||||
| 545 | if (asprintf(&(session->sess_backend.ab_name), | |||
| 546 | "AgentX(%"PRIu32"u""/%"PRIu32"u"")", | |||
| 547 | conn->conn_id, session->sess_id) == -1) { | |||
| 548 | log_warn("AgentX(%"PRIu32"u""): asprintf: Open Failed", | |||
| 549 | conn->conn_id); | |||
| 550 | error = APPL_ERROR_OPENFAILED; | |||
| 551 | goto fail; | |||
| 552 | } | |||
| 553 | session->sess_backend.ab_cookie = session; | |||
| 554 | session->sess_backend.ab_retries = 0; | |||
| 555 | session->sess_backend.ab_fn = &appl_agentx_functions; | |||
| 556 | session->sess_backend.ab_range = 1; | |||
| 557 | RB_INIT(&(session->sess_backend.ab_requests))do { (&(session->sess_backend.ab_requests))->rbh_root = ((void *)0); } while (0); | |||
| 558 | TAILQ_INSERT_TAIL(&(conn->conn_sessions), session, sess_conn_entry)do { (session)->sess_conn_entry.tqe_next = ((void *)0); (session )->sess_conn_entry.tqe_prev = (&(conn->conn_sessions ))->tqh_last; *(&(conn->conn_sessions))->tqh_last = (session); (&(conn->conn_sessions))->tqh_last = & (session)->sess_conn_entry.tqe_next; } while (0); | |||
| 559 | ||||
| 560 | appl_agentx_oid2ber_oid(&(session->sess_oid), &oid); | |||
| 561 | smi_oid2string(&oid, oidbuf, sizeof(oidbuf), 0); | |||
| 562 | log_info("%s: %s %s: Open", session->sess_backend.ab_name, oidbuf, | |||
| 563 | session->sess_descr.aos_string); | |||
| 564 | ||||
| 565 | ax_response(conn->conn_ax, session->sess_id, | |||
| 566 | pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid, | |||
| 567 | smi_getticks(), APPL_ERROR_NOERROR, 0, NULL((void *)0), 0); | |||
| 568 | event_add(&(conn->conn_wev), NULL((void *)0)); | |||
| 569 | ||||
| 570 | return; | |||
| 571 | fail: | |||
| 572 | ax_response(conn->conn_ax, 0, pdu->ap_header.aph_transactionid, | |||
| 573 | pdu->ap_header.aph_packetid, 0, error, 0, NULL((void *)0), 0); | |||
| 574 | event_add(&(conn->conn_wev), NULL((void *)0)); | |||
| 575 | if (session != NULL((void *)0)) | |||
| 576 | free(session->sess_descr.aos_string); | |||
| 577 | free(session); | |||
| 578 | } | |||
| 579 | ||||
| 580 | void | |||
| 581 | appl_agentx_close(struct appl_agentx_session *session, struct ax_pdu *pdu) | |||
| 582 | { | |||
| 583 | struct appl_agentx_connection *conn = session->sess_conn; | |||
| 584 | char name[100]; | |||
| 585 | enum appl_error error = APPL_ERROR_NOERROR; | |||
| 586 | ||||
| 587 | strlcpy(name, session->sess_backend.ab_name, sizeof(name)); | |||
| 588 | if (pdu->ap_payload.ap_close.ap_reason == AX_CLOSE_BYMANAGER) { | |||
| 589 | log_warnx("%s: Invalid close reason", name); | |||
| 590 | error = APPL_ERROR_PARSEERROR; | |||
| 591 | } else { | |||
| 592 | appl_agentx_session_free(session); | |||
| 593 | log_info("%s: Closed by subagent (%s)", name, | |||
| 594 | ax_closereason2string(pdu->ap_payload.ap_close.ap_reason)); | |||
| 595 | } | |||
| 596 | ||||
| 597 | ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid, | |||
| 598 | pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid, | |||
| 599 | smi_getticks(), error, 0, NULL((void *)0), 0); | |||
| 600 | event_add(&(conn->conn_wev), NULL((void *)0)); | |||
| 601 | if (error == APPL_ERROR_NOERROR) | |||
| 602 | return; | |||
| 603 | ||||
| 604 | appl_agentx_forceclose(&(session->sess_backend), | |||
| 605 | APPL_CLOSE_REASONPARSEERROR); | |||
| 606 | if (TAILQ_EMPTY(&(conn->conn_sessions))(((&(conn->conn_sessions))->tqh_first) == ((void *) 0))) | |||
| 607 | appl_agentx_free(conn, APPL_CLOSE_REASONOTHER); | |||
| 608 | } | |||
| 609 | ||||
| 610 | void | |||
| 611 | appl_agentx_forceclose(struct appl_backend *backend, | |||
| 612 | enum appl_close_reason reason) | |||
| 613 | { | |||
| 614 | struct appl_agentx_session *session = backend->ab_cookie; | |||
| 615 | char name[100]; | |||
| 616 | ||||
| 617 | session->sess_conn->conn_ax->ax_byteorder = session->sess_byteorder; | |||
| 618 | ax_close(session->sess_conn->conn_ax, session->sess_id, | |||
| 619 | (enum ax_close_reason) reason); | |||
| 620 | event_add(&(session->sess_conn->conn_wev), NULL((void *)0)); | |||
| 621 | ||||
| 622 | strlcpy(name, session->sess_backend.ab_name, sizeof(name)); | |||
| 623 | appl_agentx_session_free(session); | |||
| 624 | log_info("%s: Closed by snmpd (%s)", name, | |||
| 625 | ax_closereason2string((enum ax_close_reason)reason)); | |||
| 626 | } | |||
| 627 | ||||
| 628 | void | |||
| 629 | appl_agentx_session_free(struct appl_agentx_session *session) | |||
| 630 | { | |||
| 631 | struct appl_agentx_connection *conn = session->sess_conn; | |||
| 632 | ||||
| 633 | appl_close(&(session->sess_backend)); | |||
| 634 | ||||
| 635 | RB_REMOVE(appl_agentx_sessions, &appl_agentx_sessions, session)appl_agentx_sessions_RB_REMOVE(&appl_agentx_sessions, session ); | |||
| 636 | TAILQ_REMOVE(&(conn->conn_sessions), session, sess_conn_entry)do { if (((session)->sess_conn_entry.tqe_next) != ((void * )0)) (session)->sess_conn_entry.tqe_next->sess_conn_entry .tqe_prev = (session)->sess_conn_entry.tqe_prev; else (& (conn->conn_sessions))->tqh_last = (session)->sess_conn_entry .tqe_prev; *(session)->sess_conn_entry.tqe_prev = (session )->sess_conn_entry.tqe_next; ; ; } while (0); | |||
| 637 | ||||
| 638 | free(session->sess_backend.ab_name); | |||
| 639 | free(session->sess_descr.aos_string); | |||
| 640 | free(session); | |||
| 641 | } | |||
| 642 | ||||
| 643 | void | |||
| 644 | appl_agentx_register(struct appl_agentx_session *session, struct ax_pdu *pdu) | |||
| 645 | { | |||
| 646 | uint32_t timeout; | |||
| 647 | struct ber_oid oid; | |||
| 648 | enum appl_error error; | |||
| 649 | int subtree = 0; | |||
| 650 | ||||
| 651 | timeout = pdu->ap_payload.ap_register.ap_timeout; | |||
| 652 | timeout = timeout != 0 ? timeout : session->sess_timeout != 0 ? | |||
| 653 | session->sess_timeout : AGENTX_DEFAULTTIMEOUT5; | |||
| 654 | timeout *= 100; | |||
| 655 | ||||
| 656 | if (session->sess_conn->conn_backend) { | |||
| 657 | pdu->ap_payload.ap_register.ap_priority = 1; | |||
| 658 | subtree = 1; | |||
| 659 | } | |||
| 660 | if (appl_agentx_oid2ber_oid( | |||
| 661 | &(pdu->ap_payload.ap_register.ap_subtree), &oid) == NULL((void *)0)) { | |||
| 662 | log_warnx("%s: Failed to register: oid too small", | |||
| 663 | session->sess_backend.ab_name); | |||
| 664 | error = APPL_ERROR_PROCESSINGERROR; | |||
| 665 | goto fail; | |||
| 666 | } | |||
| 667 | ||||
| 668 | error = appl_register(pdu->ap_context.aos_string, timeout, | |||
| 669 | pdu->ap_payload.ap_register.ap_priority, &oid, | |||
| 670 | pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION(1 << 0), | |||
| 671 | subtree, pdu->ap_payload.ap_register.ap_range_subid, | |||
| 672 | pdu->ap_payload.ap_register.ap_upper_bound, | |||
| 673 | &(session->sess_backend)); | |||
| 674 | ||||
| 675 | fail: | |||
| 676 | ax_response(session->sess_conn->conn_ax, session->sess_id, | |||
| 677 | pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid, | |||
| 678 | smi_getticks(), error, 0, NULL((void *)0), 0); | |||
| 679 | event_add(&(session->sess_conn->conn_wev), NULL((void *)0)); | |||
| 680 | } | |||
| 681 | ||||
| 682 | void | |||
| 683 | appl_agentx_unregister(struct appl_agentx_session *session, struct ax_pdu *pdu) | |||
| 684 | { | |||
| 685 | struct ber_oid oid; | |||
| 686 | enum appl_error error; | |||
| 687 | ||||
| 688 | if (appl_agentx_oid2ber_oid( | |||
| 689 | &(pdu->ap_payload.ap_unregister.ap_subtree), &oid) == NULL((void *)0)) { | |||
| 690 | log_warnx("%s: Failed to unregister: oid too small", | |||
| 691 | session->sess_backend.ab_name); | |||
| 692 | error = APPL_ERROR_PROCESSINGERROR; | |||
| 693 | goto fail; | |||
| 694 | } | |||
| 695 | ||||
| 696 | error = appl_unregister(pdu->ap_context.aos_string, | |||
| 697 | pdu->ap_payload.ap_unregister.ap_priority, &oid, | |||
| 698 | pdu->ap_payload.ap_unregister.ap_range_subid, | |||
| 699 | pdu->ap_payload.ap_unregister.ap_upper_bound, | |||
| 700 | &(session->sess_backend)); | |||
| 701 | ||||
| 702 | fail: | |||
| 703 | ax_response(session->sess_conn->conn_ax, session->sess_id, | |||
| 704 | pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid, | |||
| 705 | smi_getticks(), error, 0, NULL((void *)0), 0); | |||
| 706 | event_add(&(session->sess_conn->conn_wev), NULL((void *)0)); | |||
| 707 | } | |||
| 708 | ||||
| 709 | #define AX_PDU_FLAG_INDEX((1 << 1) | (1 << 2)) (AX_PDU_FLAG_NEW_INDEX(1 << 1) | AX_PDU_FLAG_ANY_INDEX(1 << 2)) | |||
| 710 | ||||
| 711 | void | |||
| 712 | appl_agentx_get(struct appl_backend *backend, int32_t transactionid, | |||
| 713 | int32_t requestid, const char *ctx, struct appl_varbind *vblist) | |||
| 714 | { | |||
| 715 | struct appl_agentx_session *session = backend->ab_cookie; | |||
| 716 | struct ax_ostring *context, string; | |||
| 717 | struct appl_varbind *vb; | |||
| 718 | struct ax_searchrange *srl; | |||
| 719 | size_t i, j, nsr; | |||
| 720 | ||||
| 721 | if (session->sess_conn->conn_ax == NULL((void *)0)) | |||
| 722 | return; | |||
| 723 | ||||
| 724 | for (nsr = 0, vb = vblist; vb != NULL((void *)0); vb = vb->av_next) | |||
| 725 | nsr++; | |||
| 726 | ||||
| 727 | if ((srl = calloc(nsr, sizeof(*srl))) == NULL((void *)0)) { | |||
| 728 | log_warn(NULL((void *)0)); | |||
| 729 | appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); | |||
| 730 | return; | |||
| 731 | } | |||
| 732 | ||||
| 733 | for (i = 0, vb = vblist; i < nsr; i++, vb = vb->av_next) { | |||
| 734 | srl[i].asr_start.aoi_include = vb->av_include; | |||
| 735 | srl[i].asr_start.aoi_idlen = vb->av_oid.bo_n; | |||
| 736 | for (j = 0; j < vb->av_oid.bo_n; j++) | |||
| 737 | srl[i].asr_start.aoi_id[j] = vb->av_oid.bo_id[j]; | |||
| 738 | srl[i].asr_stop.aoi_include = 0; | |||
| 739 | srl[i].asr_stop.aoi_idlen = 0; | |||
| 740 | } | |||
| 741 | if ((context = appl_agentx_string2ostring(ctx, &string)) == NULL((void *)0)) { | |||
| 742 | if (errno(*__errno()) != 0) { | |||
| 743 | log_warn("Failed to convert context"); | |||
| 744 | appl_response(backend, requestid, | |||
| 745 | APPL_ERROR_GENERR, 1, vblist); | |||
| 746 | free(srl); | |||
| 747 | return; | |||
| 748 | } | |||
| 749 | } | |||
| 750 | ||||
| 751 | session->sess_conn->conn_ax->ax_byteorder = session->sess_byteorder; | |||
| 752 | if (ax_get(session->sess_conn->conn_ax, session->sess_id, transactionid, | |||
| 753 | requestid, context, srl, nsr) == -1) | |||
| 754 | appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); | |||
| 755 | else | |||
| 756 | event_add(&(session->sess_conn->conn_wev), NULL((void *)0)); | |||
| 757 | free(srl); | |||
| 758 | if (context != NULL((void *)0)) | |||
| 759 | free(context->aos_string); | |||
| 760 | } | |||
| 761 | ||||
| 762 | void | |||
| 763 | appl_agentx_getnext(struct appl_backend *backend, int32_t transactionid, | |||
| 764 | int32_t requestid, const char *ctx, struct appl_varbind *vblist) | |||
| 765 | { | |||
| 766 | struct appl_agentx_session *session = backend->ab_cookie; | |||
| 767 | struct ax_ostring *context, string; | |||
| 768 | struct appl_varbind *vb; | |||
| 769 | struct ax_searchrange *srl; | |||
| 770 | size_t i, j, nsr; | |||
| 771 | ||||
| 772 | if (session->sess_conn->conn_ax == NULL((void *)0)) | |||
| 773 | return; | |||
| 774 | ||||
| 775 | for (nsr = 0, vb = vblist; vb != NULL((void *)0); vb = vb->av_next) | |||
| 776 | nsr++; | |||
| 777 | ||||
| 778 | if ((srl = calloc(nsr, sizeof(*srl))) == NULL((void *)0)) { | |||
| 779 | log_warn(NULL((void *)0)); | |||
| 780 | appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); | |||
| 781 | return; | |||
| 782 | } | |||
| 783 | ||||
| 784 | for (i = 0, vb = vblist; i < nsr; i++, vb = vb->av_next) { | |||
| 785 | srl[i].asr_start.aoi_include = vb->av_include; | |||
| 786 | srl[i].asr_start.aoi_idlen = vb->av_oid.bo_n; | |||
| 787 | for (j = 0; j < vb->av_oid.bo_n; j++) | |||
| 788 | srl[i].asr_start.aoi_id[j] = vb->av_oid.bo_id[j]; | |||
| 789 | srl[i].asr_stop.aoi_include = 0; | |||
| 790 | srl[i].asr_stop.aoi_idlen = vb->av_oid_end.bo_n; | |||
| 791 | for (j = 0; j < vb->av_oid_end.bo_n; j++) | |||
| 792 | srl[i].asr_stop.aoi_id[j] = vb->av_oid_end.bo_id[j]; | |||
| 793 | } | |||
| 794 | if ((context = appl_agentx_string2ostring(ctx, &string)) == NULL((void *)0)) { | |||
| 795 | if (errno(*__errno()) != 0) { | |||
| 796 | log_warn("Failed to convert context"); | |||
| 797 | appl_response(backend, requestid, | |||
| 798 | APPL_ERROR_GENERR, 1, vblist); | |||
| 799 | free(srl); | |||
| 800 | return; | |||
| 801 | } | |||
| 802 | } | |||
| 803 | ||||
| 804 | session->sess_conn->conn_ax->ax_byteorder = session->sess_byteorder; | |||
| 805 | if (ax_getnext(session->sess_conn->conn_ax, session->sess_id, transactionid, | |||
| 806 | requestid, context, srl, nsr) == -1) | |||
| 807 | appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist); | |||
| 808 | else | |||
| 809 | event_add(&(session->sess_conn->conn_wev), NULL((void *)0)); | |||
| 810 | free(srl); | |||
| 811 | if (context != NULL((void *)0)) | |||
| 812 | free(context->aos_string); | |||
| 813 | } | |||
| 814 | ||||
| 815 | void | |||
| 816 | appl_agentx_addagentcaps(struct appl_agentx_session *session, | |||
| 817 | struct ax_pdu *pdu) | |||
| 818 | { | |||
| 819 | struct ber_oid oid; | |||
| 820 | enum appl_error error; | |||
| 821 | ||||
| 822 | if (appl_agentx_oid2ber_oid(&(pdu->ap_payload.ap_addagentcaps.ap_oid), | |||
| 823 | &oid) == NULL((void *)0)) { | |||
| 824 | log_warnx("%s: Failed to add agent capabilities: oid too small", | |||
| 825 | session->sess_backend.ab_name); | |||
| 826 | error = APPL_ERROR_PARSEERROR; | |||
| 827 | goto fail; | |||
| 828 | } | |||
| 829 | ||||
| 830 | error = appl_addagentcaps(pdu->ap_context.aos_string, &oid, | |||
| 831 | pdu->ap_payload.ap_addagentcaps.ap_descr.aos_string, | |||
| 832 | &(session->sess_backend)); | |||
| 833 | ||||
| 834 | fail: | |||
| 835 | ax_response(session->sess_conn->conn_ax, session->sess_id, | |||
| 836 | pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid, | |||
| 837 | smi_getticks(), error, 0, NULL((void *)0), 0); | |||
| 838 | event_add(&(session->sess_conn->conn_wev), NULL((void *)0)); | |||
| 839 | } | |||
| 840 | ||||
| 841 | void | |||
| 842 | appl_agentx_removeagentcaps(struct appl_agentx_session *session, | |||
| 843 | struct ax_pdu *pdu) | |||
| 844 | { | |||
| 845 | struct ber_oid oid; | |||
| 846 | enum appl_error error; | |||
| 847 | ||||
| 848 | if (appl_agentx_oid2ber_oid(&(pdu->ap_payload.ap_addagentcaps.ap_oid), | |||
| 849 | &oid) == NULL((void *)0)) { | |||
| 850 | log_warnx("%s: Failed to remove agent capabilities: " | |||
| 851 | "oid too small", session->sess_backend.ab_name); | |||
| 852 | error = APPL_ERROR_PARSEERROR; | |||
| 853 | goto fail; | |||
| 854 | } | |||
| 855 | ||||
| 856 | error = appl_removeagentcaps(pdu->ap_context.aos_string, &oid, | |||
| 857 | &(session->sess_backend)); | |||
| 858 | ||||
| 859 | fail: | |||
| 860 | ax_response(session->sess_conn->conn_ax, session->sess_id, | |||
| 861 | pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid, | |||
| 862 | smi_getticks(), error, 0, NULL((void *)0), 0); | |||
| 863 | event_add(&(session->sess_conn->conn_wev), NULL((void *)0)); | |||
| 864 | } | |||
| 865 | ||||
| 866 | void | |||
| 867 | appl_agentx_response(struct appl_agentx_session *session, struct ax_pdu *pdu) | |||
| 868 | { | |||
| 869 | struct appl_varbind *response = NULL((void *)0); | |||
| 870 | struct ax_varbind *vb; | |||
| 871 | enum appl_error error; | |||
| 872 | uint16_t index; | |||
| 873 | size_t i, nvarbind; | |||
| 874 | ||||
| 875 | nvarbind = pdu->ap_payload.ap_response.ap_nvarbind; | |||
| 876 | if ((response = calloc(nvarbind, sizeof(*response))) == NULL((void *)0)) { | |||
| 877 | log_warn(NULL((void *)0)); | |||
| 878 | appl_response(&(session->sess_backend), | |||
| 879 | pdu->ap_header.aph_packetid, | |||
| 880 | APPL_ERROR_GENERR, 1, NULL((void *)0)); | |||
| 881 | return; | |||
| 882 | } | |||
| 883 | ||||
| 884 | error = (enum appl_error)pdu->ap_payload.ap_response.ap_error; | |||
| 885 | index = pdu->ap_payload.ap_response.ap_index; | |||
| 886 | for (i = 0; i < nvarbind; i++) { | |||
| 887 | response[i].av_next = i + 1 == nvarbind ? | |||
| 888 | NULL((void *)0) : &(response[i + 1]); | |||
| 889 | vb = &(pdu->ap_payload.ap_response.ap_varbindlist[i]); | |||
| 890 | ||||
| 891 | if (appl_agentx_oid2ber_oid(&(vb->avb_oid), | |||
| 892 | &(response[i].av_oid)) == NULL((void *)0)) { | |||
| 893 | log_warnx("%s: invalid oid", | |||
| 894 | session->sess_backend.ab_name); | |||
| 895 | if (error != APPL_ERROR_NOERROR) { | |||
| 896 | error = APPL_ERROR_GENERR; | |||
| 897 | index = i + 1; | |||
| 898 | } | |||
| 899 | continue; | |||
| 900 | } | |||
| 901 | response[i].av_value = appl_agentx_value2ber_element(vb); | |||
| 902 | if (response[i].av_value == NULL((void *)0)) { | |||
| 903 | log_warn("%s: Failed to parse response value", | |||
| 904 | session->sess_backend.ab_name); | |||
| 905 | if (error != APPL_ERROR_NOERROR) { | |||
| 906 | error = APPL_ERROR_GENERR; | |||
| 907 | index = i + 1; | |||
| 908 | } | |||
| 909 | } | |||
| 910 | } | |||
| 911 | appl_response(&(session->sess_backend), pdu->ap_header.aph_packetid, | |||
| 912 | error, index, response); | |||
| 913 | free(response); | |||
| 914 | } | |||
| 915 | ||||
| 916 | void | |||
| 917 | appl_agentx_send(int fd, short event, void *cookie) | |||
| 918 | { | |||
| 919 | struct appl_agentx_connection *conn = cookie; | |||
| 920 | ||||
| 921 | switch (ax_send(conn->conn_ax)) { | |||
| 922 | case -1: | |||
| 923 | if (errno(*__errno()) == EAGAIN35) | |||
| 924 | break; | |||
| 925 | log_warn("AgentX(%"PRIu32"u"")", conn->conn_id); | |||
| 926 | ax_free(conn->conn_ax); | |||
| 927 | conn->conn_ax = NULL((void *)0); | |||
| 928 | appl_agentx_free(conn, APPL_CLOSE_REASONOTHER); | |||
| 929 | return; | |||
| 930 | case 0: | |||
| 931 | return; | |||
| 932 | default: | |||
| 933 | break; | |||
| 934 | } | |||
| 935 | event_add(&(conn->conn_wev), NULL((void *)0)); | |||
| 936 | } | |||
| 937 | ||||
| 938 | struct ber_oid * | |||
| 939 | appl_agentx_oid2ber_oid(struct ax_oid *aoid, struct ber_oid *boid) | |||
| 940 | { | |||
| 941 | size_t i; | |||
| 942 | ||||
| 943 | if (aoid->aoi_idlen < BER_MIN_OID_LEN2 || | |||
| 944 | aoid->aoi_idlen > BER_MAX_OID_LEN128) { | |||
| 945 | errno(*__errno()) = EINVAL22; | |||
| 946 | return NULL((void *)0); | |||
| 947 | } | |||
| 948 | ||||
| 949 | ||||
| 950 | boid->bo_n = aoid->aoi_idlen; | |||
| 951 | for (i = 0; i < boid->bo_n; i++) | |||
| 952 | boid->bo_id[i] = aoid->aoi_id[i]; | |||
| 953 | return boid; | |||
| 954 | } | |||
| 955 | ||||
| 956 | struct ber_element * | |||
| 957 | appl_agentx_value2ber_element(struct ax_varbind *vb) | |||
| 958 | { | |||
| 959 | struct ber_oid oid; | |||
| 960 | struct ber_element *elm; | |||
| 961 | ||||
| 962 | switch (vb->avb_type) { | |||
| 963 | case AX_DATA_TYPE_INTEGER: | |||
| 964 | return ober_add_integer(NULL((void *)0), vb->avb_data.avb_int32); | |||
| 965 | case AX_DATA_TYPE_OCTETSTRING: | |||
| 966 | return ober_add_nstring(NULL((void *)0), | |||
| 967 | vb->avb_data.avb_ostring.aos_string, | |||
| 968 | vb->avb_data.avb_ostring.aos_slen); | |||
| 969 | case AX_DATA_TYPE_NULL: | |||
| 970 | return ober_add_null(NULL((void *)0)); | |||
| 971 | case AX_DATA_TYPE_OID: | |||
| 972 | if (appl_agentx_oid2ber_oid( | |||
| 973 | &(vb->avb_data.avb_oid), &oid) == NULL((void *)0)) | |||
| 974 | return NULL((void *)0); | |||
| 975 | return ober_add_oid(NULL((void *)0), &oid); | |||
| 976 | case AX_DATA_TYPE_IPADDRESS: | |||
| 977 | if ((elm = ober_add_nstring(NULL((void *)0), | |||
| 978 | vb->avb_data.avb_ostring.aos_string, | |||
| 979 | vb->avb_data.avb_ostring.aos_slen)) == NULL((void *)0)) | |||
| 980 | return NULL((void *)0); | |||
| 981 | ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_IPADDR); | |||
| 982 | return elm; | |||
| 983 | case AX_DATA_TYPE_COUNTER32: | |||
| 984 | elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint32); | |||
| 985 | if (elm == NULL((void *)0)) | |||
| 986 | return NULL((void *)0); | |||
| 987 | ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_COUNTER32); | |||
| 988 | return elm; | |||
| 989 | case AX_DATA_TYPE_GAUGE32: | |||
| 990 | elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint32); | |||
| 991 | if (elm == NULL((void *)0)) | |||
| 992 | return NULL((void *)0); | |||
| 993 | ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_GAUGE32); | |||
| 994 | return elm; | |||
| 995 | case AX_DATA_TYPE_TIMETICKS: | |||
| 996 | elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint32); | |||
| 997 | if (elm == NULL((void *)0)) | |||
| 998 | return NULL((void *)0); | |||
| 999 | ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_TIMETICKS); | |||
| 1000 | return elm; | |||
| 1001 | case AX_DATA_TYPE_OPAQUE: | |||
| 1002 | if ((elm = ober_add_nstring(NULL((void *)0), | |||
| 1003 | vb->avb_data.avb_ostring.aos_string, | |||
| 1004 | vb->avb_data.avb_ostring.aos_slen)) == NULL((void *)0)) | |||
| 1005 | return NULL((void *)0); | |||
| 1006 | ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_OPAQUE); | |||
| 1007 | return elm; | |||
| 1008 | case AX_DATA_TYPE_COUNTER64: | |||
| 1009 | elm = ober_add_integer(NULL((void *)0), vb->avb_data.avb_uint64); | |||
| 1010 | if (elm == NULL((void *)0)) | |||
| 1011 | return NULL((void *)0); | |||
| 1012 | ober_set_header(elm, BER_CLASS_APPLICATION0x1, SNMP_T_COUNTER64); | |||
| 1013 | return elm; | |||
| 1014 | case AX_DATA_TYPE_NOSUCHOBJECT: | |||
| 1015 | return appl_exception(APPL_EXC_NOSUCHOBJECT); | |||
| 1016 | case AX_DATA_TYPE_NOSUCHINSTANCE: | |||
| 1017 | return appl_exception(APPL_EXC_NOSUCHINSTANCE); | |||
| 1018 | case AX_DATA_TYPE_ENDOFMIBVIEW: | |||
| 1019 | return appl_exception(APPL_EXC_ENDOFMIBVIEW); | |||
| 1020 | default: | |||
| 1021 | errno(*__errno()) = EINVAL22; | |||
| 1022 | return NULL((void *)0); | |||
| 1023 | } | |||
| 1024 | } | |||
| 1025 | ||||
| 1026 | struct ax_ostring * | |||
| 1027 | appl_agentx_string2ostring(const char *str, struct ax_ostring *ostring) | |||
| 1028 | { | |||
| 1029 | if (str == NULL((void *)0)) { | |||
| 1030 | errno(*__errno()) = 0; | |||
| 1031 | return NULL((void *)0); | |||
| 1032 | } | |||
| 1033 | ||||
| 1034 | ostring->aos_slen = strlen(str); | |||
| 1035 | if ((ostring->aos_string = strdup(str)) == NULL((void *)0)) | |||
| 1036 | return NULL((void *)0); | |||
| 1037 | return ostring; | |||
| 1038 | } | |||
| 1039 | ||||
| 1040 | int | |||
| 1041 | appl_agentx_cmp(struct appl_agentx_connection *conn1, | |||
| 1042 | struct appl_agentx_connection *conn2) | |||
| 1043 | { | |||
| 1044 | return conn1->conn_id < conn2->conn_id ? -1 : | |||
| 1045 | conn1->conn_id > conn2->conn_id; | |||
| 1046 | } | |||
| 1047 | ||||
| 1048 | int | |||
| 1049 | appl_agentx_session_cmp(struct appl_agentx_session *sess1, | |||
| 1050 | struct appl_agentx_session *sess2) | |||
| 1051 | { | |||
| 1052 | return sess1->sess_id < sess2->sess_id ? -1 : sess1->sess_id > sess2->sess_id; | |||
| 1053 | } | |||
| 1054 | ||||
| 1055 | RB_GENERATE_STATIC(appl_agentx_conns, appl_agentx_connection, conn_entry,__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR (struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *parent, *gparent, *tmp ; while ((parent = (elm)->conn_entry.rbe_parent) && (parent)->conn_entry.rbe_color == 1) { gparent = (parent) ->conn_entry.rbe_parent; if (parent == (gparent)->conn_entry .rbe_left) { tmp = (gparent)->conn_entry.rbe_right; if (tmp && (tmp)->conn_entry.rbe_color == 1) { (tmp)-> conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color = 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm = gparent; continue; } if ((parent)->conn_entry.rbe_right == elm) { do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left )) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent) ->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent )->conn_entry.rbe_left; if (((gparent)->conn_entry.rbe_left = (tmp)->conn_entry.rbe_right)) { ((tmp)->conn_entry.rbe_right )->conn_entry.rbe_parent = (gparent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry .rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry .rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->conn_entry.rbe_right = (gparent); (gparent)->conn_entry.rbe_parent = (tmp); do {} while (0) ; if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent)->conn_entry.rbe_left; if (tmp && (tmp)->conn_entry.rbe_color == 1) { (tmp)-> conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color = 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm = gparent; continue; } if ((parent)->conn_entry.rbe_left == elm) { do { (tmp) = (parent)->conn_entry.rbe_left; if ((( parent)->conn_entry.rbe_left = (tmp)->conn_entry.rbe_right )) { ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_right = (parent); (parent)->conn_entry.rbe_parent = ( tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent )->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent )->conn_entry.rbe_right; if (((gparent)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left )->conn_entry.rbe_parent = (gparent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry .rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry .rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->conn_entry.rbe_left = (gparent); ( gparent)->conn_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root)->conn_entry.rbe_color = 0; } __attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR (struct appl_agentx_conns *head, struct appl_agentx_connection *parent, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp; while ((elm == ((void *)0) || (elm)->conn_entry.rbe_color == 0) && elm != (head)->rbh_root) { if ((parent)-> conn_entry.rbe_left == elm) { tmp = (parent)->conn_entry.rbe_right ; if ((tmp)->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry .rbe_color = 0; (parent)->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent )->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = ( parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry.rbe_right ; } if (((tmp)->conn_entry.rbe_left == ((void *)0) || ((tmp )->conn_entry.rbe_left)->conn_entry.rbe_color == 0) && ((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)-> conn_entry.rbe_right)->conn_entry.rbe_color == 0)) { (tmp) ->conn_entry.rbe_color = 1; elm = parent; parent = (elm)-> conn_entry.rbe_parent; } else { if ((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)->conn_entry.rbe_right)->conn_entry .rbe_color == 0) { struct appl_agentx_connection *oleft; if ( (oleft = (tmp)->conn_entry.rbe_left)) (oleft)->conn_entry .rbe_color = 0; (tmp)->conn_entry.rbe_color = 1; do { (oleft ) = (tmp)->conn_entry.rbe_left; if (((tmp)->conn_entry. rbe_left = (oleft)->conn_entry.rbe_right)) { ((oleft)-> conn_entry.rbe_right)->conn_entry.rbe_parent = (tmp); } do {} while (0); if (((oleft)->conn_entry.rbe_parent = (tmp) ->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)->conn_entry .rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry.rbe_parent )->conn_entry.rbe_left = (oleft); else ((tmp)->conn_entry .rbe_parent)->conn_entry.rbe_right = (oleft); } else (head )->rbh_root = (oleft); (oleft)->conn_entry.rbe_right = ( tmp); (tmp)->conn_entry.rbe_parent = (oleft); do {} while ( 0); if (((oleft)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry.rbe_right; } (tmp )->conn_entry.rbe_color = (parent)->conn_entry.rbe_color ; (parent)->conn_entry.rbe_color = 0; if ((tmp)->conn_entry .rbe_right) ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color = 0; do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent )->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = ( parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent)->conn_entry.rbe_left; if ((tmp) ->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry.rbe_color = 0; (parent)->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->conn_entry.rbe_left; if (((parent)-> conn_entry.rbe_left = (tmp)->conn_entry.rbe_right)) { ((tmp )->conn_entry.rbe_right)->conn_entry.rbe_parent = (parent ); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = ( parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_right = (parent); (parent)->conn_entry.rbe_parent = ( tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry. rbe_left; } if (((tmp)->conn_entry.rbe_left == ((void *)0) || ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_color == 0) && ((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color == 0)) { (tmp)->conn_entry.rbe_color = 1; elm = parent; parent = (elm)->conn_entry.rbe_parent; } else { if ((tmp)->conn_entry .rbe_left == ((void *)0) || ((tmp)->conn_entry.rbe_left)-> conn_entry.rbe_color == 0) { struct appl_agentx_connection *oright ; if ((oright = (tmp)->conn_entry.rbe_right)) (oright)-> conn_entry.rbe_color = 0; (tmp)->conn_entry.rbe_color = 1; do { (oright) = (tmp)->conn_entry.rbe_right; if (((tmp)-> conn_entry.rbe_right = (oright)->conn_entry.rbe_left)) { ( (oright)->conn_entry.rbe_left)->conn_entry.rbe_parent = (tmp); } do {} while (0); if (((oright)->conn_entry.rbe_parent = (tmp)->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)-> conn_entry.rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry .rbe_parent)->conn_entry.rbe_left = (oright); else ((tmp)-> conn_entry.rbe_parent)->conn_entry.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)->conn_entry .rbe_left = (tmp); (tmp)->conn_entry.rbe_parent = (oright) ; do {} while (0); if (((oright)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry.rbe_left ; } (tmp)->conn_entry.rbe_color = (parent)->conn_entry. rbe_color; (parent)->conn_entry.rbe_color = 0; if ((tmp)-> conn_entry.rbe_left) ((tmp)->conn_entry.rbe_left)->conn_entry .rbe_color = 0; do { (tmp) = (parent)->conn_entry.rbe_left ; if (((parent)->conn_entry.rbe_left = (tmp)->conn_entry .rbe_right)) { ((tmp)->conn_entry.rbe_right)->conn_entry .rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry .rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent ) == ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left ) ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->conn_entry.rbe_right = (parent); (parent)->conn_entry .rbe_parent = (tmp); do {} while (0); if (((tmp)->conn_entry .rbe_parent)) do {} while (0); } while (0); elm = (head)-> rbh_root; break; } } } if (elm) (elm)->conn_entry.rbe_color = 0; } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_REMOVE(struct appl_agentx_conns *head , struct appl_agentx_connection *elm) { struct appl_agentx_connection *child, *parent, *old = elm; int color; if ((elm)->conn_entry .rbe_left == ((void *)0)) child = (elm)->conn_entry.rbe_right ; else if ((elm)->conn_entry.rbe_right == ((void *)0)) child = (elm)->conn_entry.rbe_left; else { struct appl_agentx_connection *left; elm = (elm)->conn_entry.rbe_right; while ((left = ( elm)->conn_entry.rbe_left)) elm = left; child = (elm)-> conn_entry.rbe_right; parent = (elm)->conn_entry.rbe_parent ; color = (elm)->conn_entry.rbe_color; if (child) (child)-> conn_entry.rbe_parent = parent; if (parent) { if ((parent)-> conn_entry.rbe_left == elm) (parent)->conn_entry.rbe_left = child; else (parent)->conn_entry.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; if ((elm)-> conn_entry.rbe_parent == old) parent = elm; (elm)->conn_entry = (old)->conn_entry; if ((old)->conn_entry.rbe_parent) { if (((old)->conn_entry.rbe_parent)->conn_entry.rbe_left == old) ((old)->conn_entry.rbe_parent)->conn_entry.rbe_left = elm; else ((old)->conn_entry.rbe_parent)->conn_entry .rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; ((old)->conn_entry.rbe_left)->conn_entry.rbe_parent = elm; if ((old)->conn_entry.rbe_right) ((old)->conn_entry .rbe_right)->conn_entry.rbe_parent = elm; if (parent) { left = parent; do { do {} while (0); } while ((left = (left)-> conn_entry.rbe_parent)); } goto color; } parent = (elm)->conn_entry .rbe_parent; color = (elm)->conn_entry.rbe_color; if (child ) (child)->conn_entry.rbe_parent = parent; if (parent) { if ((parent)->conn_entry.rbe_left == elm) (parent)->conn_entry .rbe_left = child; else (parent)->conn_entry.rbe_right = child ; do {} while (0); } else (head)->rbh_root = child; color: if (color == 0) appl_agentx_conns_RB_REMOVE_COLOR(head, parent , child); return (old); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_INSERT(struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp; struct appl_agentx_connection *parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root; while (tmp) { parent = tmp ; comp = (appl_agentx_cmp)(elm, parent); if (comp < 0) tmp = (tmp)->conn_entry.rbe_left; else if (comp > 0) tmp = (tmp)->conn_entry.rbe_right; else return (tmp); } do { (elm )->conn_entry.rbe_parent = parent; (elm)->conn_entry.rbe_left = (elm)->conn_entry.rbe_right = ((void *)0); (elm)->conn_entry .rbe_color = 1; } while (0); if (parent != ((void *)0)) { if ( comp < 0) (parent)->conn_entry.rbe_left = elm; else (parent )->conn_entry.rbe_right = elm; do {} while (0); } else (head )->rbh_root = elm; appl_agentx_conns_RB_INSERT_COLOR(head, elm); return (((void *)0)); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_FIND(struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp = (head)->rbh_root; int comp; while (tmp) { comp = appl_agentx_cmp(elm, tmp); if (comp < 0) tmp = (tmp)->conn_entry.rbe_left; else if (comp > 0) tmp = (tmp)->conn_entry.rbe_right; else return (tmp); } return (((void *)0)); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_NFIND(struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp = (head)->rbh_root; struct appl_agentx_connection *res = ((void *)0); int comp; while (tmp) { comp = appl_agentx_cmp (elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->conn_entry .rbe_left; } else if (comp > 0) tmp = (tmp)->conn_entry .rbe_right; else return (tmp); } return (res); } __attribute__ ((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_NEXT (struct appl_agentx_connection *elm) { if ((elm)->conn_entry .rbe_right) { elm = (elm)->conn_entry.rbe_right; while ((elm )->conn_entry.rbe_left) elm = (elm)->conn_entry.rbe_left ; } else { if ((elm)->conn_entry.rbe_parent && (elm == ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left )) elm = (elm)->conn_entry.rbe_parent; else { while ((elm) ->conn_entry.rbe_parent && (elm == ((elm)->conn_entry .rbe_parent)->conn_entry.rbe_right)) elm = (elm)->conn_entry .rbe_parent; elm = (elm)->conn_entry.rbe_parent; } } return (elm); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_PREV(struct appl_agentx_connection *elm ) { if ((elm)->conn_entry.rbe_left) { elm = (elm)->conn_entry .rbe_left; while ((elm)->conn_entry.rbe_right) elm = (elm) ->conn_entry.rbe_right; } else { if ((elm)->conn_entry. rbe_parent && (elm == ((elm)->conn_entry.rbe_parent )->conn_entry.rbe_right)) elm = (elm)->conn_entry.rbe_parent ; else { while ((elm)->conn_entry.rbe_parent && (elm == ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left )) elm = (elm)->conn_entry.rbe_parent; elm = (elm)->conn_entry .rbe_parent; } } return (elm); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_MINMAX( struct appl_agentx_conns *head, int val) { struct appl_agentx_connection *tmp = (head)->rbh_root; struct appl_agentx_connection *parent = ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->conn_entry.rbe_left; else tmp = (tmp)->conn_entry .rbe_right; } return (parent); } | |||
| 1056 | appl_agentx_cmp)__attribute__((__unused__)) static void appl_agentx_conns_RB_INSERT_COLOR (struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *parent, *gparent, *tmp ; while ((parent = (elm)->conn_entry.rbe_parent) && (parent)->conn_entry.rbe_color == 1) { gparent = (parent) ->conn_entry.rbe_parent; if (parent == (gparent)->conn_entry .rbe_left) { tmp = (gparent)->conn_entry.rbe_right; if (tmp && (tmp)->conn_entry.rbe_color == 1) { (tmp)-> conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color = 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm = gparent; continue; } if ((parent)->conn_entry.rbe_right == elm) { do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left )) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent) ->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent )->conn_entry.rbe_left; if (((gparent)->conn_entry.rbe_left = (tmp)->conn_entry.rbe_right)) { ((tmp)->conn_entry.rbe_right )->conn_entry.rbe_parent = (gparent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry .rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry .rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->conn_entry.rbe_right = (gparent); (gparent)->conn_entry.rbe_parent = (tmp); do {} while (0) ; if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent)->conn_entry.rbe_left; if (tmp && (tmp)->conn_entry.rbe_color == 1) { (tmp)-> conn_entry.rbe_color = 0; do { (parent)->conn_entry.rbe_color = 0; (gparent)->conn_entry.rbe_color = 1; } while (0); elm = gparent; continue; } if ((parent)->conn_entry.rbe_left == elm) { do { (tmp) = (parent)->conn_entry.rbe_left; if ((( parent)->conn_entry.rbe_left = (tmp)->conn_entry.rbe_right )) { ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_right = (parent); (parent)->conn_entry.rbe_parent = ( tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)->conn_entry.rbe_color = 0; (gparent )->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent )->conn_entry.rbe_right; if (((gparent)->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left )->conn_entry.rbe_parent = (gparent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (gparent)->conn_entry .rbe_parent)) { if ((gparent) == ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left) ((gparent)->conn_entry.rbe_parent )->conn_entry.rbe_left = (tmp); else ((gparent)->conn_entry .rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->conn_entry.rbe_left = (gparent); ( gparent)->conn_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root)->conn_entry.rbe_color = 0; } __attribute__((__unused__)) static void appl_agentx_conns_RB_REMOVE_COLOR (struct appl_agentx_conns *head, struct appl_agentx_connection *parent, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp; while ((elm == ((void *)0) || (elm)->conn_entry.rbe_color == 0) && elm != (head)->rbh_root) { if ((parent)-> conn_entry.rbe_left == elm) { tmp = (parent)->conn_entry.rbe_right ; if ((tmp)->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry .rbe_color = 0; (parent)->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent )->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = ( parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry.rbe_right ; } if (((tmp)->conn_entry.rbe_left == ((void *)0) || ((tmp )->conn_entry.rbe_left)->conn_entry.rbe_color == 0) && ((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)-> conn_entry.rbe_right)->conn_entry.rbe_color == 0)) { (tmp) ->conn_entry.rbe_color = 1; elm = parent; parent = (elm)-> conn_entry.rbe_parent; } else { if ((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)->conn_entry.rbe_right)->conn_entry .rbe_color == 0) { struct appl_agentx_connection *oleft; if ( (oleft = (tmp)->conn_entry.rbe_left)) (oleft)->conn_entry .rbe_color = 0; (tmp)->conn_entry.rbe_color = 1; do { (oleft ) = (tmp)->conn_entry.rbe_left; if (((tmp)->conn_entry. rbe_left = (oleft)->conn_entry.rbe_right)) { ((oleft)-> conn_entry.rbe_right)->conn_entry.rbe_parent = (tmp); } do {} while (0); if (((oleft)->conn_entry.rbe_parent = (tmp) ->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)->conn_entry .rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry.rbe_parent )->conn_entry.rbe_left = (oleft); else ((tmp)->conn_entry .rbe_parent)->conn_entry.rbe_right = (oleft); } else (head )->rbh_root = (oleft); (oleft)->conn_entry.rbe_right = ( tmp); (tmp)->conn_entry.rbe_parent = (oleft); do {} while ( 0); if (((oleft)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry.rbe_right; } (tmp )->conn_entry.rbe_color = (parent)->conn_entry.rbe_color ; (parent)->conn_entry.rbe_color = 0; if ((tmp)->conn_entry .rbe_right) ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color = 0; do { (tmp) = (parent)->conn_entry.rbe_right; if (((parent )->conn_entry.rbe_right = (tmp)->conn_entry.rbe_left)) { ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_parent = ( parent); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_left = (parent); (parent)->conn_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent)->conn_entry.rbe_left; if ((tmp) ->conn_entry.rbe_color == 1) { do { (tmp)->conn_entry.rbe_color = 0; (parent)->conn_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->conn_entry.rbe_left; if (((parent)-> conn_entry.rbe_left = (tmp)->conn_entry.rbe_right)) { ((tmp )->conn_entry.rbe_right)->conn_entry.rbe_parent = (parent ); } do {} while (0); if (((tmp)->conn_entry.rbe_parent = ( parent)->conn_entry.rbe_parent)) { if ((parent) == ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left) ((parent )->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->conn_entry .rbe_right = (parent); (parent)->conn_entry.rbe_parent = ( tmp); do {} while (0); if (((tmp)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry. rbe_left; } if (((tmp)->conn_entry.rbe_left == ((void *)0) || ((tmp)->conn_entry.rbe_left)->conn_entry.rbe_color == 0) && ((tmp)->conn_entry.rbe_right == ((void *)0) || ((tmp)->conn_entry.rbe_right)->conn_entry.rbe_color == 0)) { (tmp)->conn_entry.rbe_color = 1; elm = parent; parent = (elm)->conn_entry.rbe_parent; } else { if ((tmp)->conn_entry .rbe_left == ((void *)0) || ((tmp)->conn_entry.rbe_left)-> conn_entry.rbe_color == 0) { struct appl_agentx_connection *oright ; if ((oright = (tmp)->conn_entry.rbe_right)) (oright)-> conn_entry.rbe_color = 0; (tmp)->conn_entry.rbe_color = 1; do { (oright) = (tmp)->conn_entry.rbe_right; if (((tmp)-> conn_entry.rbe_right = (oright)->conn_entry.rbe_left)) { ( (oright)->conn_entry.rbe_left)->conn_entry.rbe_parent = (tmp); } do {} while (0); if (((oright)->conn_entry.rbe_parent = (tmp)->conn_entry.rbe_parent)) { if ((tmp) == ((tmp)-> conn_entry.rbe_parent)->conn_entry.rbe_left) ((tmp)->conn_entry .rbe_parent)->conn_entry.rbe_left = (oright); else ((tmp)-> conn_entry.rbe_parent)->conn_entry.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)->conn_entry .rbe_left = (tmp); (tmp)->conn_entry.rbe_parent = (oright) ; do {} while (0); if (((oright)->conn_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->conn_entry.rbe_left ; } (tmp)->conn_entry.rbe_color = (parent)->conn_entry. rbe_color; (parent)->conn_entry.rbe_color = 0; if ((tmp)-> conn_entry.rbe_left) ((tmp)->conn_entry.rbe_left)->conn_entry .rbe_color = 0; do { (tmp) = (parent)->conn_entry.rbe_left ; if (((parent)->conn_entry.rbe_left = (tmp)->conn_entry .rbe_right)) { ((tmp)->conn_entry.rbe_right)->conn_entry .rbe_parent = (parent); } do {} while (0); if (((tmp)->conn_entry .rbe_parent = (parent)->conn_entry.rbe_parent)) { if ((parent ) == ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left ) ((parent)->conn_entry.rbe_parent)->conn_entry.rbe_left = (tmp); else ((parent)->conn_entry.rbe_parent)->conn_entry .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->conn_entry.rbe_right = (parent); (parent)->conn_entry .rbe_parent = (tmp); do {} while (0); if (((tmp)->conn_entry .rbe_parent)) do {} while (0); } while (0); elm = (head)-> rbh_root; break; } } } if (elm) (elm)->conn_entry.rbe_color = 0; } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_REMOVE(struct appl_agentx_conns *head , struct appl_agentx_connection *elm) { struct appl_agentx_connection *child, *parent, *old = elm; int color; if ((elm)->conn_entry .rbe_left == ((void *)0)) child = (elm)->conn_entry.rbe_right ; else if ((elm)->conn_entry.rbe_right == ((void *)0)) child = (elm)->conn_entry.rbe_left; else { struct appl_agentx_connection *left; elm = (elm)->conn_entry.rbe_right; while ((left = ( elm)->conn_entry.rbe_left)) elm = left; child = (elm)-> conn_entry.rbe_right; parent = (elm)->conn_entry.rbe_parent ; color = (elm)->conn_entry.rbe_color; if (child) (child)-> conn_entry.rbe_parent = parent; if (parent) { if ((parent)-> conn_entry.rbe_left == elm) (parent)->conn_entry.rbe_left = child; else (parent)->conn_entry.rbe_right = child; do {} while (0); } else (head)->rbh_root = child; if ((elm)-> conn_entry.rbe_parent == old) parent = elm; (elm)->conn_entry = (old)->conn_entry; if ((old)->conn_entry.rbe_parent) { if (((old)->conn_entry.rbe_parent)->conn_entry.rbe_left == old) ((old)->conn_entry.rbe_parent)->conn_entry.rbe_left = elm; else ((old)->conn_entry.rbe_parent)->conn_entry .rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; ((old)->conn_entry.rbe_left)->conn_entry.rbe_parent = elm; if ((old)->conn_entry.rbe_right) ((old)->conn_entry .rbe_right)->conn_entry.rbe_parent = elm; if (parent) { left = parent; do { do {} while (0); } while ((left = (left)-> conn_entry.rbe_parent)); } goto color; } parent = (elm)->conn_entry .rbe_parent; color = (elm)->conn_entry.rbe_color; if (child ) (child)->conn_entry.rbe_parent = parent; if (parent) { if ((parent)->conn_entry.rbe_left == elm) (parent)->conn_entry .rbe_left = child; else (parent)->conn_entry.rbe_right = child ; do {} while (0); } else (head)->rbh_root = child; color: if (color == 0) appl_agentx_conns_RB_REMOVE_COLOR(head, parent , child); return (old); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_INSERT(struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp; struct appl_agentx_connection *parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root; while (tmp) { parent = tmp ; comp = (appl_agentx_cmp)(elm, parent); if (comp < 0) tmp = (tmp)->conn_entry.rbe_left; else if (comp > 0) tmp = (tmp)->conn_entry.rbe_right; else return (tmp); } do { (elm )->conn_entry.rbe_parent = parent; (elm)->conn_entry.rbe_left = (elm)->conn_entry.rbe_right = ((void *)0); (elm)->conn_entry .rbe_color = 1; } while (0); if (parent != ((void *)0)) { if ( comp < 0) (parent)->conn_entry.rbe_left = elm; else (parent )->conn_entry.rbe_right = elm; do {} while (0); } else (head )->rbh_root = elm; appl_agentx_conns_RB_INSERT_COLOR(head, elm); return (((void *)0)); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_FIND(struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp = (head)->rbh_root; int comp; while (tmp) { comp = appl_agentx_cmp(elm, tmp); if (comp < 0) tmp = (tmp)->conn_entry.rbe_left; else if (comp > 0) tmp = (tmp)->conn_entry.rbe_right; else return (tmp); } return (((void *)0)); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_NFIND(struct appl_agentx_conns *head, struct appl_agentx_connection *elm) { struct appl_agentx_connection *tmp = (head)->rbh_root; struct appl_agentx_connection *res = ((void *)0); int comp; while (tmp) { comp = appl_agentx_cmp (elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->conn_entry .rbe_left; } else if (comp > 0) tmp = (tmp)->conn_entry .rbe_right; else return (tmp); } return (res); } __attribute__ ((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_NEXT (struct appl_agentx_connection *elm) { if ((elm)->conn_entry .rbe_right) { elm = (elm)->conn_entry.rbe_right; while ((elm )->conn_entry.rbe_left) elm = (elm)->conn_entry.rbe_left ; } else { if ((elm)->conn_entry.rbe_parent && (elm == ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left )) elm = (elm)->conn_entry.rbe_parent; else { while ((elm) ->conn_entry.rbe_parent && (elm == ((elm)->conn_entry .rbe_parent)->conn_entry.rbe_right)) elm = (elm)->conn_entry .rbe_parent; elm = (elm)->conn_entry.rbe_parent; } } return (elm); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_PREV(struct appl_agentx_connection *elm ) { if ((elm)->conn_entry.rbe_left) { elm = (elm)->conn_entry .rbe_left; while ((elm)->conn_entry.rbe_right) elm = (elm) ->conn_entry.rbe_right; } else { if ((elm)->conn_entry. rbe_parent && (elm == ((elm)->conn_entry.rbe_parent )->conn_entry.rbe_right)) elm = (elm)->conn_entry.rbe_parent ; else { while ((elm)->conn_entry.rbe_parent && (elm == ((elm)->conn_entry.rbe_parent)->conn_entry.rbe_left )) elm = (elm)->conn_entry.rbe_parent; elm = (elm)->conn_entry .rbe_parent; } } return (elm); } __attribute__((__unused__)) static struct appl_agentx_connection * appl_agentx_conns_RB_MINMAX( struct appl_agentx_conns *head, int val) { struct appl_agentx_connection *tmp = (head)->rbh_root; struct appl_agentx_connection *parent = ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->conn_entry.rbe_left; else tmp = (tmp)->conn_entry .rbe_right; } return (parent); }; | |||
| 1057 | RB_GENERATE_STATIC(appl_agentx_sessions, appl_agentx_session, sess_entry,__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *parent, *gparent, *tmp; while ((parent = (elm)->sess_entry.rbe_parent) && (parent )->sess_entry.rbe_color == 1) { gparent = (parent)->sess_entry .rbe_parent; if (parent == (gparent)->sess_entry.rbe_left) { tmp = (gparent)->sess_entry.rbe_right; if (tmp && (tmp)->sess_entry.rbe_color == 1) { (tmp)->sess_entry. rbe_color = 0; do { (parent)->sess_entry.rbe_color = 0; (gparent )->sess_entry.rbe_color = 1; } while (0); elm = gparent; continue ; } if ((parent)->sess_entry.rbe_right == elm) { do { (tmp ) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry .rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry .rbe_left)->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry .rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)-> sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_left ; if (((gparent)->sess_entry.rbe_left = (tmp)->sess_entry .rbe_right)) { ((tmp)->sess_entry.rbe_right)->sess_entry .rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry .rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent ) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left ) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->sess_entry.rbe_right = (gparent); (gparent)->sess_entry .rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry .rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent )->sess_entry.rbe_left; if (tmp && (tmp)->sess_entry .rbe_color == 1) { (tmp)->sess_entry.rbe_color = 0; do { ( parent)->sess_entry.rbe_color = 0; (gparent)->sess_entry .rbe_color = 1; } while (0); elm = gparent; continue; } if (( parent)->sess_entry.rbe_left == elm) { do { (tmp) = (parent )->sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left = (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right )->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry. rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)-> sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_right ; if (((gparent)->sess_entry.rbe_right = (tmp)->sess_entry .rbe_left)) { ((tmp)->sess_entry.rbe_left)->sess_entry. rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry .rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent ) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left ) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->sess_entry.rbe_left = (gparent); (gparent)->sess_entry .rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry .rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root )->sess_entry.rbe_color = 0; } __attribute__((__unused__)) static void appl_agentx_sessions_RB_REMOVE_COLOR(struct appl_agentx_sessions *head, struct appl_agentx_session *parent, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp; while ((elm == ((void *)0) || (elm)->sess_entry.rbe_color == 0) && elm != (head)->rbh_root) { if ((parent)->sess_entry.rbe_left == elm) { tmp = (parent)->sess_entry.rbe_right; if ((tmp)-> sess_entry.rbe_color == 1) { do { (tmp)->sess_entry.rbe_color = 0; (parent)->sess_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->sess_entry.rbe_right; if (((parent)-> sess_entry.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp )->sess_entry.rbe_left)->sess_entry.rbe_parent = (parent ); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = ( parent)->sess_entry.rbe_parent)) { if ((parent) == ((parent )->sess_entry.rbe_parent)->sess_entry.rbe_left) ((parent )->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->sess_entry .rbe_left = (parent); (parent)->sess_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_right ; } if (((tmp)->sess_entry.rbe_left == ((void *)0) || ((tmp )->sess_entry.rbe_left)->sess_entry.rbe_color == 0) && ((tmp)->sess_entry.rbe_right == ((void *)0) || ((tmp)-> sess_entry.rbe_right)->sess_entry.rbe_color == 0)) { (tmp) ->sess_entry.rbe_color = 1; elm = parent; parent = (elm)-> sess_entry.rbe_parent; } else { if ((tmp)->sess_entry.rbe_right == ((void *)0) || ((tmp)->sess_entry.rbe_right)->sess_entry .rbe_color == 0) { struct appl_agentx_session *oleft; if ((oleft = (tmp)->sess_entry.rbe_left)) (oleft)->sess_entry.rbe_color = 0; (tmp)->sess_entry.rbe_color = 1; do { (oleft) = (tmp )->sess_entry.rbe_left; if (((tmp)->sess_entry.rbe_left = (oleft)->sess_entry.rbe_right)) { ((oleft)->sess_entry .rbe_right)->sess_entry.rbe_parent = (tmp); } do {} while ( 0); if (((oleft)->sess_entry.rbe_parent = (tmp)->sess_entry .rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)-> sess_entry.rbe_left = (oleft); else ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (oleft)->sess_entry.rbe_right = (tmp); (tmp)-> sess_entry.rbe_parent = (oleft); do {} while (0); if (((oleft )->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_right; } (tmp)->sess_entry. rbe_color = (parent)->sess_entry.rbe_color; (parent)->sess_entry .rbe_color = 0; if ((tmp)->sess_entry.rbe_right) ((tmp)-> sess_entry.rbe_right)->sess_entry.rbe_color = 0; do { (tmp ) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry .rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry .rbe_left)->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry .rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent )->sess_entry.rbe_left; if ((tmp)->sess_entry.rbe_color == 1) { do { (tmp)->sess_entry.rbe_color = 0; (parent)-> sess_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)-> sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left = ( tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right )->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry. rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_left; } if (((tmp)-> sess_entry.rbe_left == ((void *)0) || ((tmp)->sess_entry.rbe_left )->sess_entry.rbe_color == 0) && ((tmp)->sess_entry .rbe_right == ((void *)0) || ((tmp)->sess_entry.rbe_right) ->sess_entry.rbe_color == 0)) { (tmp)->sess_entry.rbe_color = 1; elm = parent; parent = (elm)->sess_entry.rbe_parent; } else { if ((tmp)->sess_entry.rbe_left == ((void *)0) || ((tmp)->sess_entry.rbe_left)->sess_entry.rbe_color == 0 ) { struct appl_agentx_session *oright; if ((oright = (tmp)-> sess_entry.rbe_right)) (oright)->sess_entry.rbe_color = 0; (tmp)->sess_entry.rbe_color = 1; do { (oright) = (tmp)-> sess_entry.rbe_right; if (((tmp)->sess_entry.rbe_right = ( oright)->sess_entry.rbe_left)) { ((oright)->sess_entry. rbe_left)->sess_entry.rbe_parent = (tmp); } do {} while (0 ); if (((oright)->sess_entry.rbe_parent = (tmp)->sess_entry .rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)-> sess_entry.rbe_left = (oright); else ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)->sess_entry.rbe_left = (tmp); (tmp)-> sess_entry.rbe_parent = (oright); do {} while (0); if (((oright )->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_left; } (tmp)->sess_entry.rbe_color = (parent)->sess_entry.rbe_color; (parent)->sess_entry .rbe_color = 0; if ((tmp)->sess_entry.rbe_left) ((tmp)-> sess_entry.rbe_left)->sess_entry.rbe_color = 0; do { (tmp) = (parent)->sess_entry.rbe_left; if (((parent)->sess_entry .rbe_left = (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry .rbe_right)->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry .rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } } if (elm) (elm)-> sess_entry.rbe_color = 0; } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_REMOVE( struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *child, *parent, *old = elm ; int color; if ((elm)->sess_entry.rbe_left == ((void *)0) ) child = (elm)->sess_entry.rbe_right; else if ((elm)-> sess_entry.rbe_right == ((void *)0)) child = (elm)->sess_entry .rbe_left; else { struct appl_agentx_session *left; elm = (elm )->sess_entry.rbe_right; while ((left = (elm)->sess_entry .rbe_left)) elm = left; child = (elm)->sess_entry.rbe_right ; parent = (elm)->sess_entry.rbe_parent; color = (elm)-> sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent = parent; if (parent) { if ((parent)->sess_entry.rbe_left == elm) (parent)->sess_entry.rbe_left = child; else (parent )->sess_entry.rbe_right = child; do {} while (0); } else ( head)->rbh_root = child; if ((elm)->sess_entry.rbe_parent == old) parent = elm; (elm)->sess_entry = (old)->sess_entry ; if ((old)->sess_entry.rbe_parent) { if (((old)->sess_entry .rbe_parent)->sess_entry.rbe_left == old) ((old)->sess_entry .rbe_parent)->sess_entry.rbe_left = elm; else ((old)->sess_entry .rbe_parent)->sess_entry.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; ((old)->sess_entry.rbe_left )->sess_entry.rbe_parent = elm; if ((old)->sess_entry.rbe_right ) ((old)->sess_entry.rbe_right)->sess_entry.rbe_parent = elm; if (parent) { left = parent; do { do {} while (0); } while ((left = (left)->sess_entry.rbe_parent)); } goto color; } parent = (elm)->sess_entry.rbe_parent; color = (elm)-> sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent = parent; if (parent) { if ((parent)->sess_entry.rbe_left == elm) (parent)->sess_entry.rbe_left = child; else (parent )->sess_entry.rbe_right = child; do {} while (0); } else ( head)->rbh_root = child; color: if (color == 0) appl_agentx_sessions_RB_REMOVE_COLOR (head, parent, child); return (old); } __attribute__((__unused__ )) static struct appl_agentx_session * appl_agentx_sessions_RB_INSERT (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp; struct appl_agentx_session *parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root ; while (tmp) { parent = tmp; comp = (appl_agentx_session_cmp )(elm, parent); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left ; else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return (tmp); } do { (elm)->sess_entry.rbe_parent = parent ; (elm)->sess_entry.rbe_left = (elm)->sess_entry.rbe_right = ((void *)0); (elm)->sess_entry.rbe_color = 1; } while ( 0); if (parent != ((void *)0)) { if (comp < 0) (parent)-> sess_entry.rbe_left = elm; else (parent)->sess_entry.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; appl_agentx_sessions_RB_INSERT_COLOR (head, elm); return (((void *)0)); } __attribute__((__unused__ )) static struct appl_agentx_session * appl_agentx_sessions_RB_FIND (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp = (head)->rbh_root ; int comp; while (tmp) { comp = appl_agentx_session_cmp(elm, tmp); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left; else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return (tmp); } return (((void *)0)); } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_NFIND (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp = (head)->rbh_root ; struct appl_agentx_session *res = ((void *)0); int comp; while (tmp) { comp = appl_agentx_session_cmp(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->sess_entry.rbe_left; } else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return (tmp); } return (res); } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_NEXT(struct appl_agentx_session *elm) { if ((elm)->sess_entry.rbe_right) { elm = (elm)-> sess_entry.rbe_right; while ((elm)->sess_entry.rbe_left) elm = (elm)->sess_entry.rbe_left; } else { if ((elm)->sess_entry .rbe_parent && (elm == ((elm)->sess_entry.rbe_parent )->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent ; else { while ((elm)->sess_entry.rbe_parent && (elm == ((elm)->sess_entry.rbe_parent)->sess_entry.rbe_right )) elm = (elm)->sess_entry.rbe_parent; elm = (elm)->sess_entry .rbe_parent; } } return (elm); } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_PREV(struct appl_agentx_session *elm) { if ((elm)->sess_entry.rbe_left ) { elm = (elm)->sess_entry.rbe_left; while ((elm)->sess_entry .rbe_right) elm = (elm)->sess_entry.rbe_right; } else { if ((elm)->sess_entry.rbe_parent && (elm == ((elm)-> sess_entry.rbe_parent)->sess_entry.rbe_right)) elm = (elm) ->sess_entry.rbe_parent; else { while ((elm)->sess_entry .rbe_parent && (elm == ((elm)->sess_entry.rbe_parent )->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent ; elm = (elm)->sess_entry.rbe_parent; } } return (elm); } __attribute__ ((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_MINMAX (struct appl_agentx_sessions *head, int val) { struct appl_agentx_session *tmp = (head)->rbh_root; struct appl_agentx_session *parent = ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->sess_entry.rbe_left; else tmp = (tmp)->sess_entry .rbe_right; } return (parent); } | |||
| 1058 | appl_agentx_session_cmp)__attribute__((__unused__)) static void appl_agentx_sessions_RB_INSERT_COLOR (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *parent, *gparent, *tmp; while ((parent = (elm)->sess_entry.rbe_parent) && (parent )->sess_entry.rbe_color == 1) { gparent = (parent)->sess_entry .rbe_parent; if (parent == (gparent)->sess_entry.rbe_left) { tmp = (gparent)->sess_entry.rbe_right; if (tmp && (tmp)->sess_entry.rbe_color == 1) { (tmp)->sess_entry. rbe_color = 0; do { (parent)->sess_entry.rbe_color = 0; (gparent )->sess_entry.rbe_color = 1; } while (0); elm = gparent; continue ; } if ((parent)->sess_entry.rbe_right == elm) { do { (tmp ) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry .rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry .rbe_left)->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry .rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)-> sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_left ; if (((gparent)->sess_entry.rbe_left = (tmp)->sess_entry .rbe_right)) { ((tmp)->sess_entry.rbe_right)->sess_entry .rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry .rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent ) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left ) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->sess_entry.rbe_right = (gparent); (gparent)->sess_entry .rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry .rbe_parent)) do {} while (0); } while (0); } else { tmp = (gparent )->sess_entry.rbe_left; if (tmp && (tmp)->sess_entry .rbe_color == 1) { (tmp)->sess_entry.rbe_color = 0; do { ( parent)->sess_entry.rbe_color = 0; (gparent)->sess_entry .rbe_color = 1; } while (0); elm = gparent; continue; } if (( parent)->sess_entry.rbe_left == elm) { do { (tmp) = (parent )->sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left = (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right )->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry. rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = parent; parent = elm; elm = tmp; } do { (parent)-> sess_entry.rbe_color = 0; (gparent)->sess_entry.rbe_color = 1; } while (0); do { (tmp) = (gparent)->sess_entry.rbe_right ; if (((gparent)->sess_entry.rbe_right = (tmp)->sess_entry .rbe_left)) { ((tmp)->sess_entry.rbe_left)->sess_entry. rbe_parent = (gparent); } do {} while (0); if (((tmp)->sess_entry .rbe_parent = (gparent)->sess_entry.rbe_parent)) { if ((gparent ) == ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left ) ((gparent)->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp); else ((gparent)->sess_entry.rbe_parent)->sess_entry .rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp) ->sess_entry.rbe_left = (gparent); (gparent)->sess_entry .rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry .rbe_parent)) do {} while (0); } while (0); } } (head->rbh_root )->sess_entry.rbe_color = 0; } __attribute__((__unused__)) static void appl_agentx_sessions_RB_REMOVE_COLOR(struct appl_agentx_sessions *head, struct appl_agentx_session *parent, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp; while ((elm == ((void *)0) || (elm)->sess_entry.rbe_color == 0) && elm != (head)->rbh_root) { if ((parent)->sess_entry.rbe_left == elm) { tmp = (parent)->sess_entry.rbe_right; if ((tmp)-> sess_entry.rbe_color == 1) { do { (tmp)->sess_entry.rbe_color = 0; (parent)->sess_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)->sess_entry.rbe_right; if (((parent)-> sess_entry.rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp )->sess_entry.rbe_left)->sess_entry.rbe_parent = (parent ); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = ( parent)->sess_entry.rbe_parent)) { if ((parent) == ((parent )->sess_entry.rbe_parent)->sess_entry.rbe_left) ((parent )->sess_entry.rbe_parent)->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry.rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)->rbh_root = (tmp); (tmp)->sess_entry .rbe_left = (parent); (parent)->sess_entry.rbe_parent = (tmp ); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_right ; } if (((tmp)->sess_entry.rbe_left == ((void *)0) || ((tmp )->sess_entry.rbe_left)->sess_entry.rbe_color == 0) && ((tmp)->sess_entry.rbe_right == ((void *)0) || ((tmp)-> sess_entry.rbe_right)->sess_entry.rbe_color == 0)) { (tmp) ->sess_entry.rbe_color = 1; elm = parent; parent = (elm)-> sess_entry.rbe_parent; } else { if ((tmp)->sess_entry.rbe_right == ((void *)0) || ((tmp)->sess_entry.rbe_right)->sess_entry .rbe_color == 0) { struct appl_agentx_session *oleft; if ((oleft = (tmp)->sess_entry.rbe_left)) (oleft)->sess_entry.rbe_color = 0; (tmp)->sess_entry.rbe_color = 1; do { (oleft) = (tmp )->sess_entry.rbe_left; if (((tmp)->sess_entry.rbe_left = (oleft)->sess_entry.rbe_right)) { ((oleft)->sess_entry .rbe_right)->sess_entry.rbe_parent = (tmp); } do {} while ( 0); if (((oleft)->sess_entry.rbe_parent = (tmp)->sess_entry .rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)-> sess_entry.rbe_left = (oleft); else ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_right = (oleft); } else (head)->rbh_root = (oleft); (oleft)->sess_entry.rbe_right = (tmp); (tmp)-> sess_entry.rbe_parent = (oleft); do {} while (0); if (((oleft )->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_right; } (tmp)->sess_entry. rbe_color = (parent)->sess_entry.rbe_color; (parent)->sess_entry .rbe_color = 0; if ((tmp)->sess_entry.rbe_right) ((tmp)-> sess_entry.rbe_right)->sess_entry.rbe_color = 0; do { (tmp ) = (parent)->sess_entry.rbe_right; if (((parent)->sess_entry .rbe_right = (tmp)->sess_entry.rbe_left)) { ((tmp)->sess_entry .rbe_left)->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry .rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_left = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } else { tmp = (parent )->sess_entry.rbe_left; if ((tmp)->sess_entry.rbe_color == 1) { do { (tmp)->sess_entry.rbe_color = 0; (parent)-> sess_entry.rbe_color = 1; } while (0); do { (tmp) = (parent)-> sess_entry.rbe_left; if (((parent)->sess_entry.rbe_left = ( tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry.rbe_right )->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry. rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_left; } if (((tmp)-> sess_entry.rbe_left == ((void *)0) || ((tmp)->sess_entry.rbe_left )->sess_entry.rbe_color == 0) && ((tmp)->sess_entry .rbe_right == ((void *)0) || ((tmp)->sess_entry.rbe_right) ->sess_entry.rbe_color == 0)) { (tmp)->sess_entry.rbe_color = 1; elm = parent; parent = (elm)->sess_entry.rbe_parent; } else { if ((tmp)->sess_entry.rbe_left == ((void *)0) || ((tmp)->sess_entry.rbe_left)->sess_entry.rbe_color == 0 ) { struct appl_agentx_session *oright; if ((oright = (tmp)-> sess_entry.rbe_right)) (oright)->sess_entry.rbe_color = 0; (tmp)->sess_entry.rbe_color = 1; do { (oright) = (tmp)-> sess_entry.rbe_right; if (((tmp)->sess_entry.rbe_right = ( oright)->sess_entry.rbe_left)) { ((oright)->sess_entry. rbe_left)->sess_entry.rbe_parent = (tmp); } do {} while (0 ); if (((oright)->sess_entry.rbe_parent = (tmp)->sess_entry .rbe_parent)) { if ((tmp) == ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((tmp)->sess_entry.rbe_parent)-> sess_entry.rbe_left = (oright); else ((tmp)->sess_entry.rbe_parent )->sess_entry.rbe_right = (oright); } else (head)->rbh_root = (oright); (oright)->sess_entry.rbe_left = (tmp); (tmp)-> sess_entry.rbe_parent = (oright); do {} while (0); if (((oright )->sess_entry.rbe_parent)) do {} while (0); } while (0); tmp = (parent)->sess_entry.rbe_left; } (tmp)->sess_entry.rbe_color = (parent)->sess_entry.rbe_color; (parent)->sess_entry .rbe_color = 0; if ((tmp)->sess_entry.rbe_left) ((tmp)-> sess_entry.rbe_left)->sess_entry.rbe_color = 0; do { (tmp) = (parent)->sess_entry.rbe_left; if (((parent)->sess_entry .rbe_left = (tmp)->sess_entry.rbe_right)) { ((tmp)->sess_entry .rbe_right)->sess_entry.rbe_parent = (parent); } do {} while (0); if (((tmp)->sess_entry.rbe_parent = (parent)->sess_entry .rbe_parent)) { if ((parent) == ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left) ((parent)->sess_entry.rbe_parent )->sess_entry.rbe_left = (tmp); else ((parent)->sess_entry .rbe_parent)->sess_entry.rbe_right = (tmp); } else (head)-> rbh_root = (tmp); (tmp)->sess_entry.rbe_right = (parent); ( parent)->sess_entry.rbe_parent = (tmp); do {} while (0); if (((tmp)->sess_entry.rbe_parent)) do {} while (0); } while (0); elm = (head)->rbh_root; break; } } } if (elm) (elm)-> sess_entry.rbe_color = 0; } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_REMOVE( struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *child, *parent, *old = elm ; int color; if ((elm)->sess_entry.rbe_left == ((void *)0) ) child = (elm)->sess_entry.rbe_right; else if ((elm)-> sess_entry.rbe_right == ((void *)0)) child = (elm)->sess_entry .rbe_left; else { struct appl_agentx_session *left; elm = (elm )->sess_entry.rbe_right; while ((left = (elm)->sess_entry .rbe_left)) elm = left; child = (elm)->sess_entry.rbe_right ; parent = (elm)->sess_entry.rbe_parent; color = (elm)-> sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent = parent; if (parent) { if ((parent)->sess_entry.rbe_left == elm) (parent)->sess_entry.rbe_left = child; else (parent )->sess_entry.rbe_right = child; do {} while (0); } else ( head)->rbh_root = child; if ((elm)->sess_entry.rbe_parent == old) parent = elm; (elm)->sess_entry = (old)->sess_entry ; if ((old)->sess_entry.rbe_parent) { if (((old)->sess_entry .rbe_parent)->sess_entry.rbe_left == old) ((old)->sess_entry .rbe_parent)->sess_entry.rbe_left = elm; else ((old)->sess_entry .rbe_parent)->sess_entry.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; ((old)->sess_entry.rbe_left )->sess_entry.rbe_parent = elm; if ((old)->sess_entry.rbe_right ) ((old)->sess_entry.rbe_right)->sess_entry.rbe_parent = elm; if (parent) { left = parent; do { do {} while (0); } while ((left = (left)->sess_entry.rbe_parent)); } goto color; } parent = (elm)->sess_entry.rbe_parent; color = (elm)-> sess_entry.rbe_color; if (child) (child)->sess_entry.rbe_parent = parent; if (parent) { if ((parent)->sess_entry.rbe_left == elm) (parent)->sess_entry.rbe_left = child; else (parent )->sess_entry.rbe_right = child; do {} while (0); } else ( head)->rbh_root = child; color: if (color == 0) appl_agentx_sessions_RB_REMOVE_COLOR (head, parent, child); return (old); } __attribute__((__unused__ )) static struct appl_agentx_session * appl_agentx_sessions_RB_INSERT (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp; struct appl_agentx_session *parent = ((void *)0); int comp = 0; tmp = (head)->rbh_root ; while (tmp) { parent = tmp; comp = (appl_agentx_session_cmp )(elm, parent); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left ; else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return (tmp); } do { (elm)->sess_entry.rbe_parent = parent ; (elm)->sess_entry.rbe_left = (elm)->sess_entry.rbe_right = ((void *)0); (elm)->sess_entry.rbe_color = 1; } while ( 0); if (parent != ((void *)0)) { if (comp < 0) (parent)-> sess_entry.rbe_left = elm; else (parent)->sess_entry.rbe_right = elm; do {} while (0); } else (head)->rbh_root = elm; appl_agentx_sessions_RB_INSERT_COLOR (head, elm); return (((void *)0)); } __attribute__((__unused__ )) static struct appl_agentx_session * appl_agentx_sessions_RB_FIND (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp = (head)->rbh_root ; int comp; while (tmp) { comp = appl_agentx_session_cmp(elm, tmp); if (comp < 0) tmp = (tmp)->sess_entry.rbe_left; else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return (tmp); } return (((void *)0)); } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_NFIND (struct appl_agentx_sessions *head, struct appl_agentx_session *elm) { struct appl_agentx_session *tmp = (head)->rbh_root ; struct appl_agentx_session *res = ((void *)0); int comp; while (tmp) { comp = appl_agentx_session_cmp(elm, tmp); if (comp < 0) { res = tmp; tmp = (tmp)->sess_entry.rbe_left; } else if (comp > 0) tmp = (tmp)->sess_entry.rbe_right; else return (tmp); } return (res); } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_NEXT(struct appl_agentx_session *elm) { if ((elm)->sess_entry.rbe_right) { elm = (elm)-> sess_entry.rbe_right; while ((elm)->sess_entry.rbe_left) elm = (elm)->sess_entry.rbe_left; } else { if ((elm)->sess_entry .rbe_parent && (elm == ((elm)->sess_entry.rbe_parent )->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent ; else { while ((elm)->sess_entry.rbe_parent && (elm == ((elm)->sess_entry.rbe_parent)->sess_entry.rbe_right )) elm = (elm)->sess_entry.rbe_parent; elm = (elm)->sess_entry .rbe_parent; } } return (elm); } __attribute__((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_PREV(struct appl_agentx_session *elm) { if ((elm)->sess_entry.rbe_left ) { elm = (elm)->sess_entry.rbe_left; while ((elm)->sess_entry .rbe_right) elm = (elm)->sess_entry.rbe_right; } else { if ((elm)->sess_entry.rbe_parent && (elm == ((elm)-> sess_entry.rbe_parent)->sess_entry.rbe_right)) elm = (elm) ->sess_entry.rbe_parent; else { while ((elm)->sess_entry .rbe_parent && (elm == ((elm)->sess_entry.rbe_parent )->sess_entry.rbe_left)) elm = (elm)->sess_entry.rbe_parent ; elm = (elm)->sess_entry.rbe_parent; } } return (elm); } __attribute__ ((__unused__)) static struct appl_agentx_session * appl_agentx_sessions_RB_MINMAX (struct appl_agentx_sessions *head, int val) { struct appl_agentx_session *tmp = (head)->rbh_root; struct appl_agentx_session *parent = ((void *)0); while (tmp) { parent = tmp; if (val < 0) tmp = (tmp)->sess_entry.rbe_left; else tmp = (tmp)->sess_entry .rbe_right; } return (parent); }; |