xref: /minix3/external/bsd/dhcp/dist/omapip/message.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: message.c,v 1.1.1.2 2014/07/12 11:57:59 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* message.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    Subroutines for dealing with message objects. */
5*83ee113eSDavid van Moolenbroek 
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 1999-2003 by Internet Software Consortium
9*83ee113eSDavid van Moolenbroek  *
10*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
11*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
12*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
13*83ee113eSDavid van Moolenbroek  *
14*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21*83ee113eSDavid van Moolenbroek  *
22*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
23*83ee113eSDavid van Moolenbroek  *   950 Charter Street
24*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
25*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
26*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
27*83ee113eSDavid van Moolenbroek  *
28*83ee113eSDavid van Moolenbroek  */
29*83ee113eSDavid van Moolenbroek 
30*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
31*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: message.c,v 1.1.1.2 2014/07/12 11:57:59 spz Exp $");
32*83ee113eSDavid van Moolenbroek 
33*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
34*83ee113eSDavid van Moolenbroek 
35*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
36*83ee113eSDavid van Moolenbroek 
OMAPI_OBJECT_ALLOC(omapi_message,omapi_message_object_t,omapi_type_message)37*83ee113eSDavid van Moolenbroek OMAPI_OBJECT_ALLOC (omapi_message,
38*83ee113eSDavid van Moolenbroek 		    omapi_message_object_t, omapi_type_message)
39*83ee113eSDavid van Moolenbroek 
40*83ee113eSDavid van Moolenbroek omapi_message_object_t *omapi_registered_messages;
41*83ee113eSDavid van Moolenbroek 
42*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line)
43*83ee113eSDavid van Moolenbroek {
44*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
45*83ee113eSDavid van Moolenbroek 	omapi_object_t *g;
46*83ee113eSDavid van Moolenbroek 	isc_result_t status;
47*83ee113eSDavid van Moolenbroek 
48*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)0;
49*83ee113eSDavid van Moolenbroek 	status = omapi_message_allocate (&m, file, line);
50*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
51*83ee113eSDavid van Moolenbroek 		return status;
52*83ee113eSDavid van Moolenbroek 
53*83ee113eSDavid van Moolenbroek 	g = (omapi_object_t *)0;
54*83ee113eSDavid van Moolenbroek 	status = omapi_generic_new (&g, file, line);
55*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
56*83ee113eSDavid van Moolenbroek 		dfree (m, file, line);
57*83ee113eSDavid van Moolenbroek 		return status;
58*83ee113eSDavid van Moolenbroek 	}
59*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&m -> inner, g, file, line);
60*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
61*83ee113eSDavid van Moolenbroek 		omapi_object_dereference ((omapi_object_t **)&m, file, line);
62*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&g, file, line);
63*83ee113eSDavid van Moolenbroek 		return status;
64*83ee113eSDavid van Moolenbroek 	}
65*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&g -> outer,
66*83ee113eSDavid van Moolenbroek 					 (omapi_object_t *)m, file, line);
67*83ee113eSDavid van Moolenbroek 
68*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
69*83ee113eSDavid van Moolenbroek 		omapi_object_dereference ((omapi_object_t **)&m, file, line);
70*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&g, file, line);
71*83ee113eSDavid van Moolenbroek 		return status;
72*83ee113eSDavid van Moolenbroek 	}
73*83ee113eSDavid van Moolenbroek 
74*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (o, (omapi_object_t *)m, file, line);
75*83ee113eSDavid van Moolenbroek 	omapi_message_dereference (&m, file, line);
76*83ee113eSDavid van Moolenbroek 	omapi_object_dereference (&g, file, line);
77*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
78*83ee113eSDavid van Moolenbroek 		return status;
79*83ee113eSDavid van Moolenbroek 
80*83ee113eSDavid van Moolenbroek 	return status;
81*83ee113eSDavid van Moolenbroek }
82*83ee113eSDavid van Moolenbroek 
omapi_message_set_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_typed_data_t * value)83*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_set_value (omapi_object_t *h,
84*83ee113eSDavid van Moolenbroek 				      omapi_object_t *id,
85*83ee113eSDavid van Moolenbroek 				      omapi_data_string_t *name,
86*83ee113eSDavid van Moolenbroek 				      omapi_typed_data_t *value)
87*83ee113eSDavid van Moolenbroek {
88*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
89*83ee113eSDavid van Moolenbroek 	isc_result_t status;
90*83ee113eSDavid van Moolenbroek 
91*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_message)
92*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
93*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)h;
94*83ee113eSDavid van Moolenbroek 
95*83ee113eSDavid van Moolenbroek 	/* Can't set authlen. */
96*83ee113eSDavid van Moolenbroek 
97*83ee113eSDavid van Moolenbroek 	/* Can set authenticator, but the value must be typed data. */
98*83ee113eSDavid van Moolenbroek 	if (!omapi_ds_strcmp (name, "authenticator")) {
99*83ee113eSDavid van Moolenbroek 		if (m -> authenticator)
100*83ee113eSDavid van Moolenbroek 			omapi_typed_data_dereference (&m -> authenticator,
101*83ee113eSDavid van Moolenbroek 						      MDL);
102*83ee113eSDavid van Moolenbroek 		omapi_typed_data_reference (&m -> authenticator, value, MDL);
103*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
104*83ee113eSDavid van Moolenbroek 
105*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "object")) {
106*83ee113eSDavid van Moolenbroek 		if (value -> type != omapi_datatype_object)
107*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
108*83ee113eSDavid van Moolenbroek 		if (m -> object)
109*83ee113eSDavid van Moolenbroek 			omapi_object_dereference (&m -> object, MDL);
110*83ee113eSDavid van Moolenbroek 		omapi_object_reference (&m -> object, value -> u.object, MDL);
111*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
112*83ee113eSDavid van Moolenbroek 
113*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "notify-object")) {
114*83ee113eSDavid van Moolenbroek 		if (value -> type != omapi_datatype_object)
115*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
116*83ee113eSDavid van Moolenbroek 		if (m -> notify_object)
117*83ee113eSDavid van Moolenbroek 			omapi_object_dereference (&m -> notify_object, MDL);
118*83ee113eSDavid van Moolenbroek 		omapi_object_reference (&m -> notify_object,
119*83ee113eSDavid van Moolenbroek 					value -> u.object, MDL);
120*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
121*83ee113eSDavid van Moolenbroek 
122*83ee113eSDavid van Moolenbroek 	/* Can set authid, but it has to be an integer. */
123*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "authid")) {
124*83ee113eSDavid van Moolenbroek 		if (value -> type != omapi_datatype_int)
125*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
126*83ee113eSDavid van Moolenbroek 		m -> authid = value -> u.integer;
127*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
128*83ee113eSDavid van Moolenbroek 
129*83ee113eSDavid van Moolenbroek 	/* Can set op, but it has to be an integer. */
130*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "op")) {
131*83ee113eSDavid van Moolenbroek 		if (value -> type != omapi_datatype_int)
132*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
133*83ee113eSDavid van Moolenbroek 		m -> op = value -> u.integer;
134*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
135*83ee113eSDavid van Moolenbroek 
136*83ee113eSDavid van Moolenbroek 	/* Handle also has to be an integer. */
137*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "handle")) {
138*83ee113eSDavid van Moolenbroek 		if (value -> type != omapi_datatype_int)
139*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
140*83ee113eSDavid van Moolenbroek 		m -> h = value -> u.integer;
141*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
142*83ee113eSDavid van Moolenbroek 
143*83ee113eSDavid van Moolenbroek 	/* Transaction ID has to be an integer. */
144*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "id")) {
145*83ee113eSDavid van Moolenbroek 		if (value -> type != omapi_datatype_int)
146*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
147*83ee113eSDavid van Moolenbroek 		m -> id = value -> u.integer;
148*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
149*83ee113eSDavid van Moolenbroek 
150*83ee113eSDavid van Moolenbroek 	/* Remote transaction ID has to be an integer. */
151*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "rid")) {
152*83ee113eSDavid van Moolenbroek 		if (value -> type != omapi_datatype_int)
153*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
154*83ee113eSDavid van Moolenbroek 		m -> rid = value -> u.integer;
155*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
156*83ee113eSDavid van Moolenbroek 	}
157*83ee113eSDavid van Moolenbroek 
158*83ee113eSDavid van Moolenbroek 	/* Try to find some inner object that can take the value. */
159*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> set_value) {
160*83ee113eSDavid van Moolenbroek 		status = ((*(h -> inner -> type -> set_value))
161*83ee113eSDavid van Moolenbroek 			  (h -> inner, id, name, value));
162*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS)
163*83ee113eSDavid van Moolenbroek 			return status;
164*83ee113eSDavid van Moolenbroek 	}
165*83ee113eSDavid van Moolenbroek 
166*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
167*83ee113eSDavid van Moolenbroek }
168*83ee113eSDavid van Moolenbroek 
omapi_message_get_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_value_t ** value)169*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_get_value (omapi_object_t *h,
170*83ee113eSDavid van Moolenbroek 				      omapi_object_t *id,
171*83ee113eSDavid van Moolenbroek 				      omapi_data_string_t *name,
172*83ee113eSDavid van Moolenbroek 				      omapi_value_t **value)
173*83ee113eSDavid van Moolenbroek {
174*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
175*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_message)
176*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
177*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)h;
178*83ee113eSDavid van Moolenbroek 
179*83ee113eSDavid van Moolenbroek 	/* Look for values that are in the message data structure. */
180*83ee113eSDavid van Moolenbroek 	if (!omapi_ds_strcmp (name, "authlen"))
181*83ee113eSDavid van Moolenbroek 		return omapi_make_int_value (value, name, (int)m -> authlen,
182*83ee113eSDavid van Moolenbroek 					     MDL);
183*83ee113eSDavid van Moolenbroek 	else if (!omapi_ds_strcmp (name, "authenticator")) {
184*83ee113eSDavid van Moolenbroek 		if (m -> authenticator)
185*83ee113eSDavid van Moolenbroek 			return omapi_make_value (value, name,
186*83ee113eSDavid van Moolenbroek 						 m -> authenticator, MDL);
187*83ee113eSDavid van Moolenbroek 		else
188*83ee113eSDavid van Moolenbroek 			return ISC_R_NOTFOUND;
189*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "authid")) {
190*83ee113eSDavid van Moolenbroek 		return omapi_make_int_value (value,
191*83ee113eSDavid van Moolenbroek 					     name, (int)m -> authid, MDL);
192*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "op")) {
193*83ee113eSDavid van Moolenbroek 		return omapi_make_int_value (value, name, (int)m -> op, MDL);
194*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "handle")) {
195*83ee113eSDavid van Moolenbroek 		return omapi_make_int_value (value, name, (int)m -> h, MDL);
196*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "id")) {
197*83ee113eSDavid van Moolenbroek 		return omapi_make_int_value (value, name, (int)m -> id, MDL);
198*83ee113eSDavid van Moolenbroek 	} else if (!omapi_ds_strcmp (name, "rid")) {
199*83ee113eSDavid van Moolenbroek 		return omapi_make_int_value (value, name, (int)m -> rid, MDL);
200*83ee113eSDavid van Moolenbroek 	}
201*83ee113eSDavid van Moolenbroek 
202*83ee113eSDavid van Moolenbroek 	/* See if there's an inner object that has the value. */
203*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> get_value)
204*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> get_value))
205*83ee113eSDavid van Moolenbroek 			(h -> inner, id, name, value);
206*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
207*83ee113eSDavid van Moolenbroek }
208*83ee113eSDavid van Moolenbroek 
omapi_message_destroy(omapi_object_t * h,const char * file,int line)209*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_destroy (omapi_object_t *h,
210*83ee113eSDavid van Moolenbroek 				    const char *file, int line)
211*83ee113eSDavid van Moolenbroek {
212*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
213*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_message)
214*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
215*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)h;
216*83ee113eSDavid van Moolenbroek 	if (m -> authenticator) {
217*83ee113eSDavid van Moolenbroek 		omapi_typed_data_dereference (&m -> authenticator, file, line);
218*83ee113eSDavid van Moolenbroek 	}
219*83ee113eSDavid van Moolenbroek 	if (!m -> prev && omapi_registered_messages != m)
220*83ee113eSDavid van Moolenbroek 		omapi_message_unregister (h);
221*83ee113eSDavid van Moolenbroek 	if (m -> id_object)
222*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&m -> id_object, file, line);
223*83ee113eSDavid van Moolenbroek 	if (m -> object)
224*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&m -> object, file, line);
225*83ee113eSDavid van Moolenbroek 	if (m -> notify_object)
226*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&m -> notify_object, file, line);
227*83ee113eSDavid van Moolenbroek 	if (m -> protocol_object)
228*83ee113eSDavid van Moolenbroek 		omapi_protocol_dereference (&m -> protocol_object, file, line);
229*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
230*83ee113eSDavid van Moolenbroek }
231*83ee113eSDavid van Moolenbroek 
omapi_message_signal_handler(omapi_object_t * h,const char * name,va_list ap)232*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_signal_handler (omapi_object_t *h,
233*83ee113eSDavid van Moolenbroek 					   const char *name, va_list ap)
234*83ee113eSDavid van Moolenbroek {
235*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
236*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_message)
237*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
238*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)h;
239*83ee113eSDavid van Moolenbroek 
240*83ee113eSDavid van Moolenbroek 	if (!strcmp (name, "status")) {
241*83ee113eSDavid van Moolenbroek 		if (m -> notify_object &&
242*83ee113eSDavid van Moolenbroek 		    m -> notify_object -> type -> signal_handler)
243*83ee113eSDavid van Moolenbroek 			return ((m -> notify_object -> type -> signal_handler))
244*83ee113eSDavid van Moolenbroek 				(m -> notify_object, name, ap);
245*83ee113eSDavid van Moolenbroek 		else if (m -> object && m -> object -> type -> signal_handler)
246*83ee113eSDavid van Moolenbroek 			return ((m -> object -> type -> signal_handler))
247*83ee113eSDavid van Moolenbroek 				(m -> object, name, ap);
248*83ee113eSDavid van Moolenbroek 	}
249*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> signal_handler)
250*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> signal_handler)) (h -> inner,
251*83ee113eSDavid van Moolenbroek 								  name, ap);
252*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
253*83ee113eSDavid van Moolenbroek }
254*83ee113eSDavid van Moolenbroek 
255*83ee113eSDavid van Moolenbroek /* Write all the published values associated with the object through the
256*83ee113eSDavid van Moolenbroek    specified connection. */
257*83ee113eSDavid van Moolenbroek 
omapi_message_stuff_values(omapi_object_t * c,omapi_object_t * id,omapi_object_t * m)258*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_stuff_values (omapi_object_t *c,
259*83ee113eSDavid van Moolenbroek 					 omapi_object_t *id,
260*83ee113eSDavid van Moolenbroek 					 omapi_object_t *m)
261*83ee113eSDavid van Moolenbroek {
262*83ee113eSDavid van Moolenbroek 	if (m -> type != omapi_type_message)
263*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
264*83ee113eSDavid van Moolenbroek 
265*83ee113eSDavid van Moolenbroek 	if (m -> inner && m -> inner -> type -> stuff_values)
266*83ee113eSDavid van Moolenbroek 		return (*(m -> inner -> type -> stuff_values)) (c, id,
267*83ee113eSDavid van Moolenbroek 								m -> inner);
268*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
269*83ee113eSDavid van Moolenbroek }
270*83ee113eSDavid van Moolenbroek 
omapi_message_register(omapi_object_t * mo)271*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_register (omapi_object_t *mo)
272*83ee113eSDavid van Moolenbroek {
273*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
274*83ee113eSDavid van Moolenbroek 
275*83ee113eSDavid van Moolenbroek 	if (mo -> type != omapi_type_message)
276*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
277*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)mo;
278*83ee113eSDavid van Moolenbroek 
279*83ee113eSDavid van Moolenbroek 	/* Already registered? */
280*83ee113eSDavid van Moolenbroek 	if (m -> prev || m -> next || omapi_registered_messages == m)
281*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
282*83ee113eSDavid van Moolenbroek 
283*83ee113eSDavid van Moolenbroek 	if (omapi_registered_messages) {
284*83ee113eSDavid van Moolenbroek 		omapi_object_reference
285*83ee113eSDavid van Moolenbroek 			((omapi_object_t **)&m -> next,
286*83ee113eSDavid van Moolenbroek 			 (omapi_object_t *)omapi_registered_messages, MDL);
287*83ee113eSDavid van Moolenbroek 		omapi_object_reference
288*83ee113eSDavid van Moolenbroek 			((omapi_object_t **)&omapi_registered_messages -> prev,
289*83ee113eSDavid van Moolenbroek 			 (omapi_object_t *)m, MDL);
290*83ee113eSDavid van Moolenbroek 		omapi_object_dereference
291*83ee113eSDavid van Moolenbroek 			((omapi_object_t **)&omapi_registered_messages, MDL);
292*83ee113eSDavid van Moolenbroek 	}
293*83ee113eSDavid van Moolenbroek 	omapi_object_reference
294*83ee113eSDavid van Moolenbroek 		((omapi_object_t **)&omapi_registered_messages,
295*83ee113eSDavid van Moolenbroek 		 (omapi_object_t *)m, MDL);
296*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;;
297*83ee113eSDavid van Moolenbroek }
298*83ee113eSDavid van Moolenbroek 
omapi_message_unregister(omapi_object_t * mo)299*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_unregister (omapi_object_t *mo)
300*83ee113eSDavid van Moolenbroek {
301*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
302*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *n;
303*83ee113eSDavid van Moolenbroek 
304*83ee113eSDavid van Moolenbroek 	if (mo -> type != omapi_type_message)
305*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
306*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)mo;
307*83ee113eSDavid van Moolenbroek 
308*83ee113eSDavid van Moolenbroek 	/* Not registered? */
309*83ee113eSDavid van Moolenbroek 	if (!m -> prev && omapi_registered_messages != m)
310*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
311*83ee113eSDavid van Moolenbroek 
312*83ee113eSDavid van Moolenbroek 	n = (omapi_message_object_t *)0;
313*83ee113eSDavid van Moolenbroek 	if (m -> next) {
314*83ee113eSDavid van Moolenbroek 		omapi_object_reference ((omapi_object_t **)&n,
315*83ee113eSDavid van Moolenbroek 					(omapi_object_t *)m -> next, MDL);
316*83ee113eSDavid van Moolenbroek 		omapi_object_dereference ((omapi_object_t **)&m -> next, MDL);
317*83ee113eSDavid van Moolenbroek 		omapi_object_dereference ((omapi_object_t **)&n -> prev, MDL);
318*83ee113eSDavid van Moolenbroek 	}
319*83ee113eSDavid van Moolenbroek 	if (m -> prev) {
320*83ee113eSDavid van Moolenbroek 		omapi_message_object_t *tmp = (omapi_message_object_t *)0;
321*83ee113eSDavid van Moolenbroek 		omapi_object_reference ((omapi_object_t **)&tmp,
322*83ee113eSDavid van Moolenbroek 					(omapi_object_t *)m -> prev, MDL);
323*83ee113eSDavid van Moolenbroek 		omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL);
324*83ee113eSDavid van Moolenbroek 		if (tmp -> next)
325*83ee113eSDavid van Moolenbroek 			omapi_object_dereference
326*83ee113eSDavid van Moolenbroek 				((omapi_object_t **)&tmp -> next, MDL);
327*83ee113eSDavid van Moolenbroek 		if (n)
328*83ee113eSDavid van Moolenbroek 			omapi_object_reference
329*83ee113eSDavid van Moolenbroek 				((omapi_object_t **)&tmp -> next,
330*83ee113eSDavid van Moolenbroek 				 (omapi_object_t *)n, MDL);
331*83ee113eSDavid van Moolenbroek 		omapi_object_dereference ((omapi_object_t **)&tmp, MDL);
332*83ee113eSDavid van Moolenbroek 	} else {
333*83ee113eSDavid van Moolenbroek 		omapi_object_dereference
334*83ee113eSDavid van Moolenbroek 			((omapi_object_t **)&omapi_registered_messages, MDL);
335*83ee113eSDavid van Moolenbroek 		if (n)
336*83ee113eSDavid van Moolenbroek 			omapi_object_reference
337*83ee113eSDavid van Moolenbroek 				((omapi_object_t **)&omapi_registered_messages,
338*83ee113eSDavid van Moolenbroek 				 (omapi_object_t *)n, MDL);
339*83ee113eSDavid van Moolenbroek 	}
340*83ee113eSDavid van Moolenbroek 	if (n)
341*83ee113eSDavid van Moolenbroek 		omapi_object_dereference ((omapi_object_t **)&n, MDL);
342*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
343*83ee113eSDavid van Moolenbroek }
344*83ee113eSDavid van Moolenbroek 
345*83ee113eSDavid van Moolenbroek #ifdef DEBUG_PROTOCOL
omapi_message_op_name(int op)346*83ee113eSDavid van Moolenbroek static const char *omapi_message_op_name(int op) {
347*83ee113eSDavid van Moolenbroek 	switch (op) {
348*83ee113eSDavid van Moolenbroek 	case OMAPI_OP_OPEN:    return "OMAPI_OP_OPEN";
349*83ee113eSDavid van Moolenbroek 	case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
350*83ee113eSDavid van Moolenbroek 	case OMAPI_OP_UPDATE:  return "OMAPI_OP_UPDATE";
351*83ee113eSDavid van Moolenbroek 	case OMAPI_OP_STATUS:  return "OMAPI_OP_STATUS";
352*83ee113eSDavid van Moolenbroek 	case OMAPI_OP_DELETE:  return "OMAPI_OP_DELETE";
353*83ee113eSDavid van Moolenbroek 	case OMAPI_OP_NOTIFY:  return "OMAPI_OP_NOTIFY";
354*83ee113eSDavid van Moolenbroek 	default:               return "(unknown op)";
355*83ee113eSDavid van Moolenbroek 	}
356*83ee113eSDavid van Moolenbroek }
357*83ee113eSDavid van Moolenbroek #endif
358*83ee113eSDavid van Moolenbroek 
359*83ee113eSDavid van Moolenbroek static isc_result_t
360*83ee113eSDavid van Moolenbroek omapi_message_process_internal (omapi_object_t *, omapi_object_t *);
361*83ee113eSDavid van Moolenbroek 
omapi_message_process(omapi_object_t * mo,omapi_object_t * po)362*83ee113eSDavid van Moolenbroek isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
363*83ee113eSDavid van Moolenbroek {
364*83ee113eSDavid van Moolenbroek 	isc_result_t status;
365*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) && 0
366*83ee113eSDavid van Moolenbroek 	unsigned long previous_outstanding = dmalloc_outstanding;
367*83ee113eSDavid van Moolenbroek #endif
368*83ee113eSDavid van Moolenbroek 
369*83ee113eSDavid van Moolenbroek 	status = omapi_message_process_internal (mo, po);
370*83ee113eSDavid van Moolenbroek 
371*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) && 0
372*83ee113eSDavid van Moolenbroek 	log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
373*83ee113eSDavid van Moolenbroek 		  dmalloc_generation,
374*83ee113eSDavid van Moolenbroek 		  dmalloc_outstanding - previous_outstanding,
375*83ee113eSDavid van Moolenbroek 		  dmalloc_outstanding, dmalloc_longterm);
376*83ee113eSDavid van Moolenbroek #endif
377*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE) && 0
378*83ee113eSDavid van Moolenbroek 	dmalloc_dump_outstanding ();
379*83ee113eSDavid van Moolenbroek #endif
380*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0
381*83ee113eSDavid van Moolenbroek 	dump_rc_history ();
382*83ee113eSDavid van Moolenbroek #endif
383*83ee113eSDavid van Moolenbroek 
384*83ee113eSDavid van Moolenbroek 	return status;
385*83ee113eSDavid van Moolenbroek }
386*83ee113eSDavid van Moolenbroek 
387*83ee113eSDavid van Moolenbroek static isc_result_t
omapi_message_process_internal(omapi_object_t * mo,omapi_object_t * po)388*83ee113eSDavid van Moolenbroek omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po)
389*83ee113eSDavid van Moolenbroek {
390*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *message, *m;
391*83ee113eSDavid van Moolenbroek 	omapi_object_t *object = (omapi_object_t *)0;
392*83ee113eSDavid van Moolenbroek 	omapi_value_t *tv = (omapi_value_t *)0;
393*83ee113eSDavid van Moolenbroek 	unsigned long create, update, exclusive;
394*83ee113eSDavid van Moolenbroek 	unsigned long wsi;
395*83ee113eSDavid van Moolenbroek 	isc_result_t status, waitstatus;
396*83ee113eSDavid van Moolenbroek 	omapi_object_type_t *type;
397*83ee113eSDavid van Moolenbroek 
398*83ee113eSDavid van Moolenbroek 	if (mo -> type != omapi_type_message)
399*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
400*83ee113eSDavid van Moolenbroek 	message = (omapi_message_object_t *)mo;
401*83ee113eSDavid van Moolenbroek 
402*83ee113eSDavid van Moolenbroek #ifdef DEBUG_PROTOCOL
403*83ee113eSDavid van Moolenbroek 	log_debug ("omapi_message_process(): "
404*83ee113eSDavid van Moolenbroek 		   "op=%s  handle=%#x  id=%#x  rid=%#x",
405*83ee113eSDavid van Moolenbroek 		   omapi_message_op_name (message -> op),
406*83ee113eSDavid van Moolenbroek 		   message -> h, message -> id, message -> rid);
407*83ee113eSDavid van Moolenbroek #endif
408*83ee113eSDavid van Moolenbroek 
409*83ee113eSDavid van Moolenbroek 	if (message -> rid) {
410*83ee113eSDavid van Moolenbroek 		for (m = omapi_registered_messages; m; m = m -> next)
411*83ee113eSDavid van Moolenbroek 			if (m -> id == message -> rid)
412*83ee113eSDavid van Moolenbroek 				break;
413*83ee113eSDavid van Moolenbroek 		/* If we don't have a real message corresponding to
414*83ee113eSDavid van Moolenbroek 		   the message ID to which this message claims it is a
415*83ee113eSDavid van Moolenbroek 		   response, something's fishy. */
416*83ee113eSDavid van Moolenbroek 		if (!m)
417*83ee113eSDavid van Moolenbroek 			return ISC_R_NOTFOUND;
418*83ee113eSDavid van Moolenbroek 		/* The authenticator on responses must match the initial
419*83ee113eSDavid van Moolenbroek 		   message. */
420*83ee113eSDavid van Moolenbroek 		if (message -> authid != m -> authid)
421*83ee113eSDavid van Moolenbroek 			return ISC_R_NOTFOUND;
422*83ee113eSDavid van Moolenbroek 	} else {
423*83ee113eSDavid van Moolenbroek 		m = (omapi_message_object_t *)0;
424*83ee113eSDavid van Moolenbroek 
425*83ee113eSDavid van Moolenbroek 		/* All messages must have an authenticator, with the exception
426*83ee113eSDavid van Moolenbroek 		   of messages that are opening a new authenticator. */
427*83ee113eSDavid van Moolenbroek 		if (omapi_protocol_authenticated(po) &&
428*83ee113eSDavid van Moolenbroek 		    !message->id_object &&
429*83ee113eSDavid van Moolenbroek 		    message->op != OMAPI_OP_OPEN) {
430*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
431*83ee113eSDavid van Moolenbroek 				(po, message->id_object, DHCP_R_NOKEYS,
432*83ee113eSDavid van Moolenbroek 				 message->id, "No authenticator on message");
433*83ee113eSDavid van Moolenbroek 		}
434*83ee113eSDavid van Moolenbroek 	}
435*83ee113eSDavid van Moolenbroek 
436*83ee113eSDavid van Moolenbroek 	switch (message -> op) {
437*83ee113eSDavid van Moolenbroek 	      case OMAPI_OP_OPEN:
438*83ee113eSDavid van Moolenbroek 		if (m) {
439*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
440*83ee113eSDavid van Moolenbroek 				(po, message->id_object, DHCP_R_INVALIDARG,
441*83ee113eSDavid van Moolenbroek 				 message->id, "OPEN can't be a response");
442*83ee113eSDavid van Moolenbroek 		}
443*83ee113eSDavid van Moolenbroek 
444*83ee113eSDavid van Moolenbroek 		/* Get the type of the requested object, if one was
445*83ee113eSDavid van Moolenbroek 		   specified. */
446*83ee113eSDavid van Moolenbroek 		status = omapi_get_value_str (mo, message -> id_object,
447*83ee113eSDavid van Moolenbroek 					      "type", &tv);
448*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS &&
449*83ee113eSDavid van Moolenbroek 		    (tv -> value -> type == omapi_datatype_data ||
450*83ee113eSDavid van Moolenbroek 		     tv -> value -> type == omapi_datatype_string)) {
451*83ee113eSDavid van Moolenbroek 			for (type = omapi_object_types;
452*83ee113eSDavid van Moolenbroek 			     type; type = type -> next)
453*83ee113eSDavid van Moolenbroek 				if (!omapi_td_strcmp (tv -> value,
454*83ee113eSDavid van Moolenbroek 						      type -> name))
455*83ee113eSDavid van Moolenbroek 					break;
456*83ee113eSDavid van Moolenbroek 		} else
457*83ee113eSDavid van Moolenbroek 			type = (omapi_object_type_t *)0;
458*83ee113eSDavid van Moolenbroek 		if (tv)
459*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&tv, MDL);
460*83ee113eSDavid van Moolenbroek 
461*83ee113eSDavid van Moolenbroek 		/* If this object had no authenticator, the requested object
462*83ee113eSDavid van Moolenbroek 		   must be an authenticator object. */
463*83ee113eSDavid van Moolenbroek 		if (omapi_protocol_authenticated(po) &&
464*83ee113eSDavid van Moolenbroek 		    !message->id_object &&
465*83ee113eSDavid van Moolenbroek 		    type != omapi_type_auth_key) {
466*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
467*83ee113eSDavid van Moolenbroek 				(po, message->id_object, DHCP_R_NOKEYS,
468*83ee113eSDavid van Moolenbroek 				 message->id, "No authenticator on message");
469*83ee113eSDavid van Moolenbroek 		}
470*83ee113eSDavid van Moolenbroek 
471*83ee113eSDavid van Moolenbroek 		/* Get the create flag. */
472*83ee113eSDavid van Moolenbroek 		status = omapi_get_value_str (mo, message -> id_object,
473*83ee113eSDavid van Moolenbroek 					      "create", &tv);
474*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS) {
475*83ee113eSDavid van Moolenbroek 			status = omapi_get_int_value (&create, tv -> value);
476*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&tv, MDL);
477*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
478*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
479*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
480*83ee113eSDavid van Moolenbroek 					 status, message -> id,
481*83ee113eSDavid van Moolenbroek 					 "invalid create flag value");
482*83ee113eSDavid van Moolenbroek 			}
483*83ee113eSDavid van Moolenbroek 		} else
484*83ee113eSDavid van Moolenbroek 			create = 0;
485*83ee113eSDavid van Moolenbroek 
486*83ee113eSDavid van Moolenbroek 		/* Get the update flag. */
487*83ee113eSDavid van Moolenbroek 		status = omapi_get_value_str (mo, message -> id_object,
488*83ee113eSDavid van Moolenbroek 					      "update", &tv);
489*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS) {
490*83ee113eSDavid van Moolenbroek 			status = omapi_get_int_value (&update, tv -> value);
491*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&tv, MDL);
492*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
493*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
494*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
495*83ee113eSDavid van Moolenbroek 					 status, message -> id,
496*83ee113eSDavid van Moolenbroek 					 "invalid update flag value");
497*83ee113eSDavid van Moolenbroek 			}
498*83ee113eSDavid van Moolenbroek 		} else
499*83ee113eSDavid van Moolenbroek 			update = 0;
500*83ee113eSDavid van Moolenbroek 
501*83ee113eSDavid van Moolenbroek 		/* Get the exclusive flag. */
502*83ee113eSDavid van Moolenbroek 		status = omapi_get_value_str (mo, message -> id_object,
503*83ee113eSDavid van Moolenbroek 					      "exclusive", &tv);
504*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS) {
505*83ee113eSDavid van Moolenbroek 			status = omapi_get_int_value (&exclusive, tv -> value);
506*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&tv, MDL);
507*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
508*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
509*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
510*83ee113eSDavid van Moolenbroek 					 status, message -> id,
511*83ee113eSDavid van Moolenbroek 					 "invalid exclusive flag value");
512*83ee113eSDavid van Moolenbroek 			}
513*83ee113eSDavid van Moolenbroek 		} else
514*83ee113eSDavid van Moolenbroek 			exclusive = 0;
515*83ee113eSDavid van Moolenbroek 
516*83ee113eSDavid van Moolenbroek 		/* If we weren't given a type, look the object up with
517*83ee113eSDavid van Moolenbroek                    the handle. */
518*83ee113eSDavid van Moolenbroek 		if (!type) {
519*83ee113eSDavid van Moolenbroek 			if (create) {
520*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
521*83ee113eSDavid van Moolenbroek 					(po, message->id_object,
522*83ee113eSDavid van Moolenbroek 					 DHCP_R_INVALIDARG,
523*83ee113eSDavid van Moolenbroek 					 message->id,
524*83ee113eSDavid van Moolenbroek 					 "type required on create");
525*83ee113eSDavid van Moolenbroek 			}
526*83ee113eSDavid van Moolenbroek 			goto refresh;
527*83ee113eSDavid van Moolenbroek 		}
528*83ee113eSDavid van Moolenbroek 
529*83ee113eSDavid van Moolenbroek 		/* If the type doesn't provide a lookup method, we can't
530*83ee113eSDavid van Moolenbroek 		   look up the object. */
531*83ee113eSDavid van Moolenbroek 		if (!type -> lookup) {
532*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
533*83ee113eSDavid van Moolenbroek 				(po, message -> id_object,
534*83ee113eSDavid van Moolenbroek 				 ISC_R_NOTIMPLEMENTED, message -> id,
535*83ee113eSDavid van Moolenbroek 				 "unsearchable object type");
536*83ee113eSDavid van Moolenbroek 		}
537*83ee113eSDavid van Moolenbroek 
538*83ee113eSDavid van Moolenbroek 		status = (*(type -> lookup)) (&object, message -> id_object,
539*83ee113eSDavid van Moolenbroek 					      message -> object);
540*83ee113eSDavid van Moolenbroek 
541*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS &&
542*83ee113eSDavid van Moolenbroek 		    status != ISC_R_NOTFOUND &&
543*83ee113eSDavid van Moolenbroek 		    status != DHCP_R_NOKEYS) {
544*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
545*83ee113eSDavid van Moolenbroek 				(po, message -> id_object,
546*83ee113eSDavid van Moolenbroek 				 status, message -> id,
547*83ee113eSDavid van Moolenbroek 				 "object lookup failed");
548*83ee113eSDavid van Moolenbroek 		}
549*83ee113eSDavid van Moolenbroek 
550*83ee113eSDavid van Moolenbroek 		/* If we didn't find the object and we aren't supposed to
551*83ee113eSDavid van Moolenbroek 		   create it, return an error. */
552*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_NOTFOUND && !create) {
553*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
554*83ee113eSDavid van Moolenbroek 				(po, message -> id_object,
555*83ee113eSDavid van Moolenbroek 				 ISC_R_NOTFOUND, message -> id,
556*83ee113eSDavid van Moolenbroek 				 "no object matches specification");
557*83ee113eSDavid van Moolenbroek 		}
558*83ee113eSDavid van Moolenbroek 
559*83ee113eSDavid van Moolenbroek 		/* If we found an object, we're supposed to be creating an
560*83ee113eSDavid van Moolenbroek 		   object, and we're not supposed to have found an object,
561*83ee113eSDavid van Moolenbroek 		   return an error. */
562*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS && create && exclusive) {
563*83ee113eSDavid van Moolenbroek 			omapi_object_dereference (&object, MDL);
564*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
565*83ee113eSDavid van Moolenbroek 				(po, message -> id_object,
566*83ee113eSDavid van Moolenbroek 				 ISC_R_EXISTS, message -> id,
567*83ee113eSDavid van Moolenbroek 				 "specified object already exists");
568*83ee113eSDavid van Moolenbroek 		}
569*83ee113eSDavid van Moolenbroek 
570*83ee113eSDavid van Moolenbroek 		/* If we're creating the object, do it now. */
571*83ee113eSDavid van Moolenbroek 		if (!object) {
572*83ee113eSDavid van Moolenbroek 			status = omapi_object_create (&object,
573*83ee113eSDavid van Moolenbroek 						      message -> id_object,
574*83ee113eSDavid van Moolenbroek 						      type);
575*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
576*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
577*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
578*83ee113eSDavid van Moolenbroek 					 status, message -> id,
579*83ee113eSDavid van Moolenbroek 					 "can't create new object");
580*83ee113eSDavid van Moolenbroek 			}
581*83ee113eSDavid van Moolenbroek 		}
582*83ee113eSDavid van Moolenbroek 
583*83ee113eSDavid van Moolenbroek 		/* If we're updating it, do so now. */
584*83ee113eSDavid van Moolenbroek 		if (create || update) {
585*83ee113eSDavid van Moolenbroek 			/* This check does not belong here. */
586*83ee113eSDavid van Moolenbroek 			if (object -> type == omapi_type_auth_key) {
587*83ee113eSDavid van Moolenbroek 				omapi_object_dereference (&object, MDL);
588*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
589*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
590*83ee113eSDavid van Moolenbroek 					 status, message -> id,
591*83ee113eSDavid van Moolenbroek 					 "can't update object");
592*83ee113eSDavid van Moolenbroek 			}
593*83ee113eSDavid van Moolenbroek 
594*83ee113eSDavid van Moolenbroek 			status = omapi_object_update (object,
595*83ee113eSDavid van Moolenbroek 						      message -> id_object,
596*83ee113eSDavid van Moolenbroek 						      message -> object,
597*83ee113eSDavid van Moolenbroek 						      message -> h);
598*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
599*83ee113eSDavid van Moolenbroek 				omapi_object_dereference (&object, MDL);
600*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
601*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
602*83ee113eSDavid van Moolenbroek 					 status, message -> id,
603*83ee113eSDavid van Moolenbroek 					 "can't update object");
604*83ee113eSDavid van Moolenbroek 			}
605*83ee113eSDavid van Moolenbroek 		}
606*83ee113eSDavid van Moolenbroek 
607*83ee113eSDavid van Moolenbroek 		/* If this is an authenticator object, add it to the active
608*83ee113eSDavid van Moolenbroek 		   set for the connection. */
609*83ee113eSDavid van Moolenbroek 		if (object -> type == omapi_type_auth_key) {
610*83ee113eSDavid van Moolenbroek 			omapi_handle_t handle;
611*83ee113eSDavid van Moolenbroek 			status = omapi_object_handle (&handle, object);
612*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
613*83ee113eSDavid van Moolenbroek 				omapi_object_dereference (&object, MDL);
614*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
615*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
616*83ee113eSDavid van Moolenbroek 					 status, message -> id,
617*83ee113eSDavid van Moolenbroek 					 "can't select authenticator");
618*83ee113eSDavid van Moolenbroek 			}
619*83ee113eSDavid van Moolenbroek 
620*83ee113eSDavid van Moolenbroek 			status = omapi_protocol_add_auth (po, object, handle);
621*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
622*83ee113eSDavid van Moolenbroek 				omapi_object_dereference (&object, MDL);
623*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
624*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
625*83ee113eSDavid van Moolenbroek 					 status, message -> id,
626*83ee113eSDavid van Moolenbroek 					 "can't select authenticator");
627*83ee113eSDavid van Moolenbroek 			}
628*83ee113eSDavid van Moolenbroek 		}
629*83ee113eSDavid van Moolenbroek 
630*83ee113eSDavid van Moolenbroek 		/* Now send the new contents of the object back in
631*83ee113eSDavid van Moolenbroek 		   response. */
632*83ee113eSDavid van Moolenbroek 		goto send;
633*83ee113eSDavid van Moolenbroek 
634*83ee113eSDavid van Moolenbroek 	      case OMAPI_OP_REFRESH:
635*83ee113eSDavid van Moolenbroek 	      refresh:
636*83ee113eSDavid van Moolenbroek 		status = omapi_handle_lookup (&object, message -> h);
637*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
638*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
639*83ee113eSDavid van Moolenbroek 				(po, message -> id_object,
640*83ee113eSDavid van Moolenbroek 				 status, message -> id,
641*83ee113eSDavid van Moolenbroek 				 "no matching handle");
642*83ee113eSDavid van Moolenbroek 		}
643*83ee113eSDavid van Moolenbroek 	      send:
644*83ee113eSDavid van Moolenbroek 		status = omapi_protocol_send_update (po, message -> id_object,
645*83ee113eSDavid van Moolenbroek 						     message -> id, object);
646*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&object, MDL);
647*83ee113eSDavid van Moolenbroek 		return status;
648*83ee113eSDavid van Moolenbroek 
649*83ee113eSDavid van Moolenbroek 	      case OMAPI_OP_UPDATE:
650*83ee113eSDavid van Moolenbroek 		if (m && m -> object) {
651*83ee113eSDavid van Moolenbroek 			status = omapi_object_reference (&object, m -> object,
652*83ee113eSDavid van Moolenbroek 									MDL);
653*83ee113eSDavid van Moolenbroek 		} else {
654*83ee113eSDavid van Moolenbroek 			status = omapi_handle_lookup (&object, message -> h);
655*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
656*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
657*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
658*83ee113eSDavid van Moolenbroek 					 status, message -> id,
659*83ee113eSDavid van Moolenbroek 					 "no matching handle");
660*83ee113eSDavid van Moolenbroek 			}
661*83ee113eSDavid van Moolenbroek 		}
662*83ee113eSDavid van Moolenbroek 
663*83ee113eSDavid van Moolenbroek 		if (object -> type == omapi_type_auth_key ||
664*83ee113eSDavid van Moolenbroek 		    (object -> inner &&
665*83ee113eSDavid van Moolenbroek 		     object -> inner -> type == omapi_type_auth_key)) {
666*83ee113eSDavid van Moolenbroek 			if (!m) {
667*83ee113eSDavid van Moolenbroek 				omapi_object_dereference (&object, MDL);
668*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
669*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
670*83ee113eSDavid van Moolenbroek 					 status, message -> id,
671*83ee113eSDavid van Moolenbroek 					 "cannot update authenticator");
672*83ee113eSDavid van Moolenbroek 			}
673*83ee113eSDavid van Moolenbroek 
674*83ee113eSDavid van Moolenbroek 			status = omapi_protocol_add_auth (po, object,
675*83ee113eSDavid van Moolenbroek 							  message -> h);
676*83ee113eSDavid van Moolenbroek 		} else {
677*83ee113eSDavid van Moolenbroek 			status = omapi_object_update (object,
678*83ee113eSDavid van Moolenbroek 						      message -> id_object,
679*83ee113eSDavid van Moolenbroek 						      message -> object,
680*83ee113eSDavid van Moolenbroek 						      message -> h);
681*83ee113eSDavid van Moolenbroek 		}
682*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
683*83ee113eSDavid van Moolenbroek 			omapi_object_dereference (&object, MDL);
684*83ee113eSDavid van Moolenbroek 			if (!message -> rid)
685*83ee113eSDavid van Moolenbroek 				return omapi_protocol_send_status
686*83ee113eSDavid van Moolenbroek 					(po, message -> id_object,
687*83ee113eSDavid van Moolenbroek 					 status, message -> id,
688*83ee113eSDavid van Moolenbroek 					 "can't update object");
689*83ee113eSDavid van Moolenbroek 			if (m)
690*83ee113eSDavid van Moolenbroek 				omapi_signal ((omapi_object_t *)m,
691*83ee113eSDavid van Moolenbroek 					      "status", status,
692*83ee113eSDavid van Moolenbroek 					      (omapi_typed_data_t *)0);
693*83ee113eSDavid van Moolenbroek 			return ISC_R_SUCCESS;
694*83ee113eSDavid van Moolenbroek 		}
695*83ee113eSDavid van Moolenbroek 		if (!message -> rid)
696*83ee113eSDavid van Moolenbroek 			status = omapi_protocol_send_status
697*83ee113eSDavid van Moolenbroek 				(po, message -> id_object, ISC_R_SUCCESS,
698*83ee113eSDavid van Moolenbroek 				 message -> id, (char *)0);
699*83ee113eSDavid van Moolenbroek 		if (m) {
700*83ee113eSDavid van Moolenbroek 			omapi_signal ((omapi_object_t *)m,
701*83ee113eSDavid van Moolenbroek 				      "status", ISC_R_SUCCESS,
702*83ee113eSDavid van Moolenbroek 				      (omapi_typed_data_t *)0);
703*83ee113eSDavid van Moolenbroek 			omapi_message_unregister ((omapi_object_t *)m);
704*83ee113eSDavid van Moolenbroek 		}
705*83ee113eSDavid van Moolenbroek 
706*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&object, MDL);
707*83ee113eSDavid van Moolenbroek 
708*83ee113eSDavid van Moolenbroek 		return status;
709*83ee113eSDavid van Moolenbroek 
710*83ee113eSDavid van Moolenbroek 	      case OMAPI_OP_NOTIFY:
711*83ee113eSDavid van Moolenbroek 		return omapi_protocol_send_status
712*83ee113eSDavid van Moolenbroek 			(po, message -> id_object, ISC_R_NOTIMPLEMENTED,
713*83ee113eSDavid van Moolenbroek 			 message -> id, "notify not implemented yet");
714*83ee113eSDavid van Moolenbroek 
715*83ee113eSDavid van Moolenbroek 	      case OMAPI_OP_STATUS:
716*83ee113eSDavid van Moolenbroek 		/* The return status of a request. */
717*83ee113eSDavid van Moolenbroek 		if (!m)
718*83ee113eSDavid van Moolenbroek 			return ISC_R_UNEXPECTED;
719*83ee113eSDavid van Moolenbroek 
720*83ee113eSDavid van Moolenbroek 		/* Get the wait status. */
721*83ee113eSDavid van Moolenbroek 		status = omapi_get_value_str (mo, message -> id_object,
722*83ee113eSDavid van Moolenbroek 					      "result", &tv);
723*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS) {
724*83ee113eSDavid van Moolenbroek 			status = omapi_get_int_value (&wsi, tv -> value);
725*83ee113eSDavid van Moolenbroek 			waitstatus = wsi;
726*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&tv, MDL);
727*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS)
728*83ee113eSDavid van Moolenbroek 				waitstatus = ISC_R_UNEXPECTED;
729*83ee113eSDavid van Moolenbroek 		} else
730*83ee113eSDavid van Moolenbroek 			waitstatus = ISC_R_UNEXPECTED;
731*83ee113eSDavid van Moolenbroek 
732*83ee113eSDavid van Moolenbroek 		status = omapi_get_value_str (mo, message -> id_object,
733*83ee113eSDavid van Moolenbroek 					      "message", &tv);
734*83ee113eSDavid van Moolenbroek 		omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
735*83ee113eSDavid van Moolenbroek 		if (status == ISC_R_SUCCESS)
736*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&tv, MDL);
737*83ee113eSDavid van Moolenbroek 
738*83ee113eSDavid van Moolenbroek 		omapi_message_unregister((omapi_object_t *)m);
739*83ee113eSDavid van Moolenbroek 
740*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
741*83ee113eSDavid van Moolenbroek 
742*83ee113eSDavid van Moolenbroek 	      case OMAPI_OP_DELETE:
743*83ee113eSDavid van Moolenbroek 		status = omapi_handle_lookup (&object, message -> h);
744*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
745*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
746*83ee113eSDavid van Moolenbroek 				(po, message -> id_object,
747*83ee113eSDavid van Moolenbroek 				 status, message -> id,
748*83ee113eSDavid van Moolenbroek 				 "no matching handle");
749*83ee113eSDavid van Moolenbroek 		}
750*83ee113eSDavid van Moolenbroek 
751*83ee113eSDavid van Moolenbroek 		if (!object -> type -> remove)
752*83ee113eSDavid van Moolenbroek 			return omapi_protocol_send_status
753*83ee113eSDavid van Moolenbroek 				(po, message -> id_object,
754*83ee113eSDavid van Moolenbroek 				 ISC_R_NOTIMPLEMENTED, message -> id,
755*83ee113eSDavid van Moolenbroek 				 "no remove method for object");
756*83ee113eSDavid van Moolenbroek 
757*83ee113eSDavid van Moolenbroek 		status = (*(object -> type -> remove)) (object,
758*83ee113eSDavid van Moolenbroek 							message -> id_object);
759*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&object, MDL);
760*83ee113eSDavid van Moolenbroek 
761*83ee113eSDavid van Moolenbroek 		return omapi_protocol_send_status (po, message -> id_object,
762*83ee113eSDavid van Moolenbroek 						   status, message -> id,
763*83ee113eSDavid van Moolenbroek 						   (char *)0);
764*83ee113eSDavid van Moolenbroek 	}
765*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTIMPLEMENTED;
766*83ee113eSDavid van Moolenbroek }
767