message.c 19.6 KB
Newer Older
Ted Lemon's avatar
Ted Lemon committed
1 2 3 4 5
/* message.c

   Subroutines for dealing with message objects. */

/*
Ted Lemon's avatar
Ted Lemon committed
6 7
 * Copyright (c) 1999-2000 Internet Software Consortium.
 * All rights reserved.
Ted Lemon's avatar
Ted Lemon committed
8
 *
Ted Lemon's avatar
Ted Lemon committed
9 10 11
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
Ted Lemon's avatar
Ted Lemon committed
12
 *
Ted Lemon's avatar
Ted Lemon committed
13 14 15 16 17 18 19 20
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of The Internet Software Consortium nor the names
 *    of its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
Ted Lemon's avatar
Ted Lemon committed
21
 *
Ted Lemon's avatar
Ted Lemon committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This software has been written for the Internet Software Consortium
 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
 * To learn more about the Internet Software Consortium, see
 * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
 * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
 * ``http://www.nominum.com''.
Ted Lemon's avatar
Ted Lemon committed
42 43
 */

44
#include <omapip/omapip_p.h>
Ted Lemon's avatar
Ted Lemon committed
45

46 47 48
OMAPI_OBJECT_ALLOC (omapi_message,
		    omapi_message_object_t, omapi_type_message)

Ted Lemon's avatar
Ted Lemon committed
49 50
omapi_message_object_t *omapi_registered_messages;

Ted Lemon's avatar
Ted Lemon committed
51
isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line)
Ted Lemon's avatar
Ted Lemon committed
52 53
{
	omapi_message_object_t *m;
54
	omapi_object_t *g;
Ted Lemon's avatar
Ted Lemon committed
55 56
	isc_result_t status;

57
	m = dmalloc (sizeof *m, file, line);
Ted Lemon's avatar
Ted Lemon committed
58 59 60 61
	if (!m)
		return ISC_R_NOMEMORY;
	memset (m, 0, sizeof *m);
	m -> type = omapi_type_message;
62
	rc_register (file, line, &m, m, m -> refcnt);
Ted Lemon's avatar
Ted Lemon committed
63 64
	m -> refcnt = 1;

65
	g = (omapi_object_t *)0;
Ted Lemon's avatar
Ted Lemon committed
66
	status = omapi_generic_new (&g, file, line);
67
	if (status != ISC_R_SUCCESS) {
68
		dfree (m, file, line);
69 70
		return status;
	}
Ted Lemon's avatar
Ted Lemon committed
71
	status = omapi_object_reference (&m -> inner, g, file, line);
72
	if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
73
		omapi_object_dereference ((omapi_object_t **)&m, file, line);
74
		omapi_object_dereference (&g, file, line);
75 76 77
		return status;
	}
	status = omapi_object_reference (&g -> outer,
Ted Lemon's avatar
Ted Lemon committed
78
					 (omapi_object_t *)m, file, line);
79 80

	if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
81
		omapi_object_dereference ((omapi_object_t **)&m, file, line);
82
		omapi_object_dereference (&g, file, line);
83 84 85
		return status;
	}

Ted Lemon's avatar
Ted Lemon committed
86 87 88
	status = omapi_object_reference (o, (omapi_object_t *)m, file, line);
	omapi_object_dereference ((omapi_object_t **)&m, file, line);
	omapi_object_dereference (&g, file, line);
89 90 91
	if (status != ISC_R_SUCCESS)
		return status;

Ted Lemon's avatar
Ted Lemon committed
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
	return status;
}

isc_result_t omapi_message_set_value (omapi_object_t *h,
				      omapi_object_t *id,
				      omapi_data_string_t *name,
				      omapi_typed_data_t *value)
{
	omapi_message_object_t *m;
	isc_result_t status;

	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)h;

	/* Can't set authlen. */

	/* Can set authenticator, but the value must be typed data. */
	if (!omapi_ds_strcmp (name, "authenticator")) {
		if (m -> authenticator)
112 113 114
			omapi_typed_data_dereference (&m -> authenticator,
						      MDL);
		omapi_typed_data_reference (&m -> authenticator, value, MDL);
Ted Lemon's avatar
Ted Lemon committed
115 116
		return ISC_R_SUCCESS;

117 118 119 120
	} else if (!omapi_ds_strcmp (name, "object")) {
		if (value -> type != omapi_datatype_object)
			return ISC_R_INVALIDARG;
		if (m -> object)
121 122
			omapi_object_dereference (&m -> object, MDL);
		omapi_object_reference (&m -> object, value -> u.object, MDL);
123 124
		return ISC_R_SUCCESS;

125 126 127 128
	} else if (!omapi_ds_strcmp (name, "notify-object")) {
		if (value -> type != omapi_datatype_object)
			return ISC_R_INVALIDARG;
		if (m -> notify_object)
129
			omapi_object_dereference (&m -> notify_object, MDL);
130
		omapi_object_reference (&m -> notify_object,
Ted Lemon's avatar
Ted Lemon committed
131
					value -> u.object, MDL);
132 133
		return ISC_R_SUCCESS;

Ted Lemon's avatar
Ted Lemon committed
134 135 136 137 138
	/* Can set authid, but it has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "authid")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> authid = value -> u.integer;
139
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
140 141 142 143 144 145

	/* Can set op, but it has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "op")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> op = value -> u.integer;
146
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
147 148 149 150 151 152

	/* Handle also has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "handle")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> h = value -> u.integer;
153
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
154 155 156 157 158 159

	/* Transaction ID has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "id")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> id = value -> u.integer;
160
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
161 162 163 164 165 166

	/* Remote transaction ID has to be an integer. */
	} else if (!omapi_ds_strcmp (name, "rid")) {
		if (value -> type != omapi_datatype_int)
			return ISC_R_INVALIDARG;
		m -> rid = value -> u.integer;
167
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	}

	/* Try to find some inner object that can take the value. */
	if (h -> inner && h -> inner -> type -> set_value) {
		status = ((*(h -> inner -> type -> set_value))
			  (h -> inner, id, name, value));
		if (status == ISC_R_SUCCESS)
			return status;
	}
			  
	return ISC_R_NOTFOUND;
}

isc_result_t omapi_message_get_value (omapi_object_t *h,
				      omapi_object_t *id,
				      omapi_data_string_t *name,
				      omapi_value_t **value)
{
	omapi_message_object_t *m;
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)h;

	/* Look for values that are in the message data structure. */
	if (!omapi_ds_strcmp (name, "authlen"))
193
		return omapi_make_int_value (value, name, (int)m -> authlen,
Ted Lemon's avatar
Ted Lemon committed
194
					     MDL);
Ted Lemon's avatar
Ted Lemon committed
195 196
	else if (!omapi_ds_strcmp (name, "authenticator")) {
		if (m -> authenticator)
Ted Lemon's avatar
Ted Lemon committed
197 198
			return omapi_make_value (value, name,
						 m -> authenticator, MDL);
Ted Lemon's avatar
Ted Lemon committed
199 200 201
		else
			return ISC_R_NOTFOUND;
	} else if (!omapi_ds_strcmp (name, "authid")) {
Ted Lemon's avatar
Ted Lemon committed
202 203
		return omapi_make_int_value (value,
					     name, (int)m -> authid, MDL);
Ted Lemon's avatar
Ted Lemon committed
204
	} else if (!omapi_ds_strcmp (name, "op")) {
Ted Lemon's avatar
Ted Lemon committed
205
		return omapi_make_int_value (value, name, (int)m -> op, MDL);
Ted Lemon's avatar
Ted Lemon committed
206
	} else if (!omapi_ds_strcmp (name, "handle")) {
Ted Lemon's avatar
Ted Lemon committed
207
		return omapi_make_int_value (value, name, (int)m -> h, MDL);
Ted Lemon's avatar
Ted Lemon committed
208
	} else if (!omapi_ds_strcmp (name, "id")) {
Ted Lemon's avatar
Ted Lemon committed
209
		return omapi_make_int_value (value, name, (int)m -> id, MDL);
Ted Lemon's avatar
Ted Lemon committed
210
	} else if (!omapi_ds_strcmp (name, "rid")) {
Ted Lemon's avatar
Ted Lemon committed
211
		return omapi_make_int_value (value, name, (int)m -> rid, MDL);
Ted Lemon's avatar
Ted Lemon committed
212 213 214 215 216 217 218 219 220
	}

	/* See if there's an inner object that has the value. */
	if (h -> inner && h -> inner -> type -> get_value)
		return (*(h -> inner -> type -> get_value))
			(h -> inner, id, name, value);
	return ISC_R_NOTFOUND;
}

Ted Lemon's avatar
Ted Lemon committed
221 222
isc_result_t omapi_message_destroy (omapi_object_t *h,
				    const char *file, int line)
Ted Lemon's avatar
Ted Lemon committed
223 224 225 226 227 228
{
	int i;

	omapi_message_object_t *m;
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
229
	m = (omapi_message_object_t *)h;
Ted Lemon's avatar
Ted Lemon committed
230
	if (m -> authenticator) {
Ted Lemon's avatar
Ted Lemon committed
231
		omapi_typed_data_dereference (&m -> authenticator, file, line);
Ted Lemon's avatar
Ted Lemon committed
232 233 234 235 236
	}
	if (!m -> prev && omapi_registered_messages != m)
		omapi_message_unregister (h);
	if (m -> id_object)
		omapi_object_dereference ((omapi_object_t **)&m -> id_object,
Ted Lemon's avatar
Ted Lemon committed
237
					  file, line);
Ted Lemon's avatar
Ted Lemon committed
238 239
	if (m -> object)
		omapi_object_dereference ((omapi_object_t **)&m -> object,
Ted Lemon's avatar
Ted Lemon committed
240
					  file, line);
Ted Lemon's avatar
Ted Lemon committed
241 242 243 244
	return ISC_R_SUCCESS;
}

isc_result_t omapi_message_signal_handler (omapi_object_t *h,
245
					   const char *name, va_list ap)
Ted Lemon's avatar
Ted Lemon committed
246
{
Ted Lemon's avatar
Ted Lemon committed
247
	omapi_message_object_t *m;
Ted Lemon's avatar
Ted Lemon committed
248 249
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
Ted Lemon's avatar
Ted Lemon committed
250
	m = (omapi_message_object_t *)h;
Ted Lemon's avatar
Ted Lemon committed
251
	
252 253 254 255 256 257 258 259
	if (!strcmp (name, "status") && 
	    (m -> object || m -> notify_object)) {
		if (m -> object)
			return ((m -> object -> type -> signal_handler))
				(m -> object, name, ap);
		else
			return ((m -> notify_object -> type -> signal_handler))
				(m -> notify_object, name, ap);
Ted Lemon's avatar
Ted Lemon committed
260
	}
Ted Lemon's avatar
Ted Lemon committed
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
	if (h -> inner && h -> inner -> type -> signal_handler)
		return (*(h -> inner -> type -> signal_handler)) (h -> inner,
								  name, ap);
	return ISC_R_NOTFOUND;
}

/* Write all the published values associated with the object through the
   specified connection. */

isc_result_t omapi_message_stuff_values (omapi_object_t *c,
					 omapi_object_t *id,
					 omapi_object_t *m)
{
	int i;

	if (m -> type != omapi_type_message)
		return ISC_R_INVALIDARG;

	if (m -> inner && m -> inner -> type -> stuff_values)
		return (*(m -> inner -> type -> stuff_values)) (c, id,
								m -> inner);
	return ISC_R_SUCCESS;
}

isc_result_t omapi_message_register (omapi_object_t *mo)
{
	omapi_message_object_t *m;

	if (mo -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)mo;
	
	/* Already registered? */
	if (m -> prev || m -> next || omapi_registered_messages == m)
		return ISC_R_INVALIDARG;

	if (omapi_registered_messages) {
		omapi_object_reference
			((omapi_object_t **)&m -> next,
300
			 (omapi_object_t *)omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
301 302
		omapi_object_reference
			((omapi_object_t **)&omapi_registered_messages -> prev,
303
			 (omapi_object_t *)m, MDL);
Ted Lemon's avatar
Ted Lemon committed
304
		omapi_object_dereference
305
			((omapi_object_t **)&omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
306 307 308
	}
	omapi_object_reference
		((omapi_object_t **)&omapi_registered_messages,
309
		 (omapi_object_t *)m, MDL);
Ted Lemon's avatar
Ted Lemon committed
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
	return ISC_R_SUCCESS;;
}

isc_result_t omapi_message_unregister (omapi_object_t *mo)
{
	omapi_message_object_t *m;
	omapi_message_object_t *n;

	if (mo -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	m = (omapi_message_object_t *)mo;
	
	/* Not registered? */
	if (!m -> prev && omapi_registered_messages != m)
		return ISC_R_INVALIDARG;

	n = (omapi_message_object_t *)0;
	if (m -> next) {
		omapi_object_reference ((omapi_object_t **)&n,
Ted Lemon's avatar
Ted Lemon committed
329 330
					(omapi_object_t *)m -> next, MDL);
		omapi_object_dereference ((omapi_object_t **)&m -> next, MDL);
Ted Lemon's avatar
Ted Lemon committed
331 332 333 334
	}
	if (m -> prev) {
		omapi_message_object_t *tmp = (omapi_message_object_t *)0;
		omapi_object_reference ((omapi_object_t **)&tmp,
Ted Lemon's avatar
Ted Lemon committed
335 336
					(omapi_object_t *)m -> prev, MDL);
		omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL);
Ted Lemon's avatar
Ted Lemon committed
337 338
		if (tmp -> next)
			omapi_object_dereference
Ted Lemon's avatar
Ted Lemon committed
339
				((omapi_object_t **)&tmp -> next, MDL);
Ted Lemon's avatar
Ted Lemon committed
340 341 342
		if (n)
			omapi_object_reference
				((omapi_object_t **)&tmp -> next,
Ted Lemon's avatar
Ted Lemon committed
343 344
				 (omapi_object_t *)n, MDL);
		omapi_object_dereference ((omapi_object_t **)&tmp, MDL);
Ted Lemon's avatar
Ted Lemon committed
345 346
	} else {
		omapi_object_dereference
Ted Lemon's avatar
Ted Lemon committed
347
			((omapi_object_t **)&omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
348 349 350
		if (n)
			omapi_object_reference
				((omapi_object_t **)&omapi_registered_messages,
Ted Lemon's avatar
Ted Lemon committed
351
				 (omapi_object_t *)n, MDL);
Ted Lemon's avatar
Ted Lemon committed
352 353
	}
	if (n)
Ted Lemon's avatar
Ted Lemon committed
354
		omapi_object_dereference ((omapi_object_t **)&n, MDL);
Ted Lemon's avatar
Ted Lemon committed
355 356
	return ISC_R_SUCCESS;
}
357 358 359 360 361

isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
{
	omapi_message_object_t *message, *m;
	omapi_object_t *object = (omapi_object_t *)0;
Ted Lemon's avatar
Ted Lemon committed
362
	omapi_value_t *tv = (omapi_value_t *)0;
363 364
	unsigned long create, update, exclusive;
	unsigned long wsi;
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
	isc_result_t status, waitstatus;
	omapi_object_type_t *type;

	if (mo -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
	message = (omapi_message_object_t *)mo;

	if (message -> rid) {
		for (m = omapi_registered_messages; m; m = m -> next)
			if (m -> id == message -> rid)
				break;
		/* If we don't have a real message corresponding to
		   the message ID to which this message claims it is a
		   response, something's fishy. */
		if (!m)
			return ISC_R_NOTFOUND;
Ted Lemon's avatar
Ted Lemon committed
381 382
	} else
		m = (omapi_message_object_t *)0;
383 384 385 386

	switch (message -> op) {
	      case OMAPI_OP_OPEN:
		if (m) {
Ted Lemon's avatar
Ted Lemon committed
387 388 389
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0, ISC_R_INVALIDARG,
				 message -> id, "OPEN can't be a response");
390 391 392 393
		}

		/* Get the type of the requested object, if one was
		   specified. */
Ted Lemon's avatar
Ted Lemon committed
394
		status = omapi_get_value_str (mo, (omapi_object_t *)0,
395 396 397 398 399 400 401 402 403 404 405 406
					      "type", &tv);
		if (status == ISC_R_SUCCESS &&
		    (tv -> value -> type == omapi_datatype_data ||
		     tv -> value -> type == omapi_datatype_string)) {
			for (type = omapi_object_types;
			     type; type = type -> next)
				if (!omapi_td_strcmp (tv -> value,
						      type -> name))
					break;
		} else
			type = (omapi_object_type_t *)0;
		if (tv)
Ted Lemon's avatar
Ted Lemon committed
407
			omapi_value_dereference (&tv, MDL);
408 409

		/* Get the create flag. */
Ted Lemon's avatar
Ted Lemon committed
410
		status = omapi_get_value_str (mo,
411 412 413
					      (omapi_object_t *)0,
					      "create", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
414
			status = omapi_get_int_value (&create, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
415
			omapi_value_dereference (&tv, MDL);
416
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
417 418 419
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
420 421 422 423 424 425
					 "invalid create flag value");
			}
		} else
			create = 0;

		/* Get the update flag. */
Ted Lemon's avatar
Ted Lemon committed
426
		status = omapi_get_value_str (mo,
427 428 429
					      (omapi_object_t *)0,
					      "update", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
430
			status = omapi_get_int_value (&update, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
431
			omapi_value_dereference (&tv, MDL);
432
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
433 434 435
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
436 437 438 439 440 441
					 "invalid update flag value");
			}
		} else
			update = 0;

		/* Get the exclusive flag. */
Ted Lemon's avatar
Ted Lemon committed
442
		status = omapi_get_value_str (mo,
443 444 445
					      (omapi_object_t *)0,
					      "exclusive", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
446
			status = omapi_get_int_value (&exclusive, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
447
			omapi_value_dereference (&tv, MDL);
448
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
449 450 451
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
452 453 454 455 456 457 458 459 460
					 "invalid exclusive flag value");
			}
		} else
			exclusive = 0;

		/* If we weren't given a type, look the object up with
                   the handle. */
		if (!type) {
			if (create) {
Ted Lemon's avatar
Ted Lemon committed
461 462 463
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 ISC_R_INVALIDARG, message -> id,
464 465 466 467 468 469 470 471
					 "type required on create");
			}
			goto refresh;
		}

		/* If the type doesn't provide a lookup method, we can't
		   look up the object. */
		if (!type -> lookup) {
Ted Lemon's avatar
Ted Lemon committed
472 473 474
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_NOTIMPLEMENTED, message -> id,
475 476
				 "unsearchable object type");
		}
477 478 479 480 481 482 483

		if (!message -> object) {
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_NOTFOUND, message -> id,
				 "no lookup key specified");
		}
484 485 486
		status = (*(type -> lookup)) (&object, (omapi_object_t *)0,
					      message -> object);

487 488 489
		if (status != ISC_R_SUCCESS &&
		    status != ISC_R_NOTFOUND &&
		    status != ISC_R_NOKEYS) {
Ted Lemon's avatar
Ted Lemon committed
490 491 492
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 status, message -> id,
493 494 495 496 497 498
				 "object lookup failed");
		}

		/* If we didn't find the object and we aren't supposed to
		   create it, return an error. */
		if (status == ISC_R_NOTFOUND && !create) {
Ted Lemon's avatar
Ted Lemon committed
499 500 501
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_NOTFOUND, message -> id,
502 503 504 505 506 507 508
				 "no object matches specification");
		}			

		/* If we found an object, we're supposed to be creating an
		   object, and we're not supposed to have found an object,
		   return an error. */
		if (status == ISC_R_SUCCESS && create && exclusive) {
Ted Lemon's avatar
Ted Lemon committed
509
			omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
510 511 512
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_EXISTS, message -> id,
513 514 515 516 517
				 "specified object already exists");
		}

		/* If we're creating the object, do it now. */
		if (!object) {
Ted Lemon's avatar
Ted Lemon committed
518 519 520
			status = omapi_object_create (&object,
						      (omapi_object_t *)0,
						      type);
521
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
522 523 524
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
525 526 527 528 529 530 531
					 "can't create new object");
			}
		}

		/* If we're updating it, do so now. */
		if (create || update) {
			status = omapi_object_update (object,
Ted Lemon's avatar
Ted Lemon committed
532
						      (omapi_object_t *)0,
533
						      message -> object,
Ted Lemon's avatar
Ted Lemon committed
534
						      message -> h);
535
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
536
				omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
537 538 539
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
540 541 542 543 544 545 546 547 548 549
					 "can't update object");
			}
		}
		
		/* Now send the new contents of the object back in
		   response. */
		goto send;

	      case OMAPI_OP_REFRESH:
	      refresh:
Ted Lemon's avatar
Ted Lemon committed
550
		status = omapi_handle_lookup (&object, message -> h);
551
		if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
552 553 554
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 status, message -> id,
555 556 557
				 "no matching handle");
		}
	      send:		
Ted Lemon's avatar
Ted Lemon committed
558 559
		status = omapi_protocol_send_update (po, (omapi_object_t *)0,
						     message -> id, object);
Ted Lemon's avatar
Ted Lemon committed
560
		omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
561
		return status;
562 563

	      case OMAPI_OP_UPDATE:
Ted Lemon's avatar
Ted Lemon committed
564
		if (m -> object) {
Ted Lemon's avatar
Ted Lemon committed
565
			omapi_object_reference (&object, m -> object, MDL);
566
		} else {
Ted Lemon's avatar
Ted Lemon committed
567
			status = omapi_handle_lookup (&object, message -> h);
568
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
569 570 571
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
572 573 574 575
					 "no matching handle");
			}
		}

Ted Lemon's avatar
Ted Lemon committed
576
		status = omapi_object_update (object, (omapi_object_t *)0,
577
					      message -> object,
Ted Lemon's avatar
Ted Lemon committed
578
					      message -> h);
579
		if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
580
			omapi_object_dereference (&object, MDL);
581
			if (!message -> rid)
Ted Lemon's avatar
Ted Lemon committed
582 583 584
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
585 586 587
					 "can't update object");
			if (m)
				omapi_signal ((omapi_object_t *)m,
Ted Lemon's avatar
Ted Lemon committed
588 589
					      "status", status,
					      (omapi_typed_data_t *)0);
590 591 592
			return ISC_R_SUCCESS;
		}
		if (!message -> rid)
Ted Lemon's avatar
Ted Lemon committed
593 594 595
			status = omapi_protocol_send_status
				(po, (omapi_object_t *)0, ISC_R_SUCCESS,
				 message -> id, (char *)0);
596 597
		if (m)
			omapi_signal ((omapi_object_t *)m,
Ted Lemon's avatar
Ted Lemon committed
598 599 600
				      "status", ISC_R_SUCCESS,
				      (omapi_typed_data_t *)0);
		return status;
601 602

	      case OMAPI_OP_NOTIFY:
Ted Lemon's avatar
Ted Lemon committed
603 604 605
		return omapi_protocol_send_status
			(po, (omapi_object_t *)0, ISC_R_NOTIMPLEMENTED,
			 message -> id, "notify not implemented yet");
606

Ted Lemon's avatar
Ted Lemon committed
607 608
	      case OMAPI_OP_STATUS:
		/* The return status of a request. */
609 610 611 612
		if (!m)
			return ISC_R_UNEXPECTED;

		/* Get the wait status. */
Ted Lemon's avatar
Ted Lemon committed
613
		status = omapi_get_value_str (mo,
614 615 616
					      (omapi_object_t *)0,
					      "result", &tv);
		if (status == ISC_R_SUCCESS) {
617 618
			status = omapi_get_int_value (&wsi, tv -> value);
			waitstatus = wsi;
Ted Lemon's avatar
Ted Lemon committed
619
			omapi_value_dereference (&tv, MDL);
620 621 622 623 624
			if (status != ISC_R_SUCCESS)
				waitstatus = ISC_R_UNEXPECTED;
		} else
			waitstatus = ISC_R_UNEXPECTED;

Ted Lemon's avatar
Ted Lemon committed
625 626 627 628 629
		status = omapi_get_value_str (mo,
					      (omapi_object_t *)0,
					      "message", &tv);
		omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
		if (status == ISC_R_SUCCESS)
Ted Lemon's avatar
Ted Lemon committed
630
			omapi_value_dereference (&tv, MDL);
631
		return ISC_R_SUCCESS;
632 633

	      case OMAPI_OP_DELETE:
Ted Lemon's avatar
Ted Lemon committed
634
		status = omapi_handle_lookup (&object, message -> h);
635 636 637 638 639 640 641
		if (status != ISC_R_SUCCESS) {
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 status, message -> id,
				 "no matching handle");
		}

642
		if (!object -> type -> remove)
643 644 645
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_NOTIMPLEMENTED, message -> id,
646
				 "no remove method for object");
647

648
		status = (*(object -> type -> remove)) (object,
649
							(omapi_object_t *)0);
Ted Lemon's avatar
Ted Lemon committed
650
		omapi_object_dereference (&object, MDL);
651 652 653 654

		return omapi_protocol_send_status (po, (omapi_object_t *)0,
						   status, message -> id,
						   (char *)0);
655 656 657
	}
	return ISC_R_NOTIMPLEMENTED;
}