message.c 19.5 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

omapi_message_object_t *omapi_registered_messages;

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

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

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

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

Ted Lemon's avatar
Ted Lemon committed
83 84 85
	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);
86 87 88
	if (status != ISC_R_SUCCESS)
		return status;

Ted Lemon's avatar
Ted Lemon committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
	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)
109 110 111
			omapi_typed_data_dereference (&m -> authenticator,
						      MDL);
		omapi_typed_data_reference (&m -> authenticator, value, MDL);
Ted Lemon's avatar
Ted Lemon committed
112 113
		return ISC_R_SUCCESS;

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

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

Ted Lemon's avatar
Ted Lemon committed
131 132 133 134 135
	/* 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;
136
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
137 138 139 140 141 142

	/* 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;
143
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
144 145 146 147 148 149

	/* 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;
150
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
151 152 153 154 155 156

	/* 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;
157
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
158 159 160 161 162 163

	/* 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;
164
		return ISC_R_SUCCESS;
Ted Lemon's avatar
Ted Lemon committed
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
	}

	/* 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"))
190
		return omapi_make_int_value (value, name, (int)m -> authlen,
Ted Lemon's avatar
Ted Lemon committed
191
					     MDL);
Ted Lemon's avatar
Ted Lemon committed
192 193
	else if (!omapi_ds_strcmp (name, "authenticator")) {
		if (m -> authenticator)
Ted Lemon's avatar
Ted Lemon committed
194 195
			return omapi_make_value (value, name,
						 m -> authenticator, MDL);
Ted Lemon's avatar
Ted Lemon committed
196 197 198
		else
			return ISC_R_NOTFOUND;
	} else if (!omapi_ds_strcmp (name, "authid")) {
Ted Lemon's avatar
Ted Lemon committed
199 200
		return omapi_make_int_value (value,
					     name, (int)m -> authid, MDL);
Ted Lemon's avatar
Ted Lemon committed
201
	} else if (!omapi_ds_strcmp (name, "op")) {
Ted Lemon's avatar
Ted Lemon committed
202
		return omapi_make_int_value (value, name, (int)m -> op, MDL);
Ted Lemon's avatar
Ted Lemon committed
203
	} else if (!omapi_ds_strcmp (name, "handle")) {
Ted Lemon's avatar
Ted Lemon committed
204
		return omapi_make_int_value (value, name, (int)m -> h, MDL);
Ted Lemon's avatar
Ted Lemon committed
205
	} else if (!omapi_ds_strcmp (name, "id")) {
Ted Lemon's avatar
Ted Lemon committed
206
		return omapi_make_int_value (value, name, (int)m -> id, MDL);
Ted Lemon's avatar
Ted Lemon committed
207
	} else if (!omapi_ds_strcmp (name, "rid")) {
Ted Lemon's avatar
Ted Lemon committed
208
		return omapi_make_int_value (value, name, (int)m -> rid, MDL);
Ted Lemon's avatar
Ted Lemon committed
209 210 211 212 213 214 215 216 217
	}

	/* 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
218 219
isc_result_t omapi_message_destroy (omapi_object_t *h,
				    const char *file, int line)
Ted Lemon's avatar
Ted Lemon committed
220 221 222 223 224 225
{
	int i;

	omapi_message_object_t *m;
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
226
	m = (omapi_message_object_t *)h;
Ted Lemon's avatar
Ted Lemon committed
227
	if (m -> authenticator) {
Ted Lemon's avatar
Ted Lemon committed
228
		omapi_typed_data_dereference (&m -> authenticator, file, line);
Ted Lemon's avatar
Ted Lemon committed
229 230 231 232 233
	}
	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
234
					  file, line);
Ted Lemon's avatar
Ted Lemon committed
235 236
	if (m -> object)
		omapi_object_dereference ((omapi_object_t **)&m -> object,
Ted Lemon's avatar
Ted Lemon committed
237
					  file, line);
Ted Lemon's avatar
Ted Lemon committed
238 239 240 241
	return ISC_R_SUCCESS;
}

isc_result_t omapi_message_signal_handler (omapi_object_t *h,
242
					   const char *name, va_list ap)
Ted Lemon's avatar
Ted Lemon committed
243
{
Ted Lemon's avatar
Ted Lemon committed
244
	omapi_message_object_t *m;
Ted Lemon's avatar
Ted Lemon committed
245 246
	if (h -> type != omapi_type_message)
		return ISC_R_INVALIDARG;
Ted Lemon's avatar
Ted Lemon committed
247
	m = (omapi_message_object_t *)h;
Ted Lemon's avatar
Ted Lemon committed
248
	
249 250 251 252 253 254 255 256
	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
257
	}
Ted Lemon's avatar
Ted Lemon committed
258 259 260 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
	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,
297
			 (omapi_object_t *)omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
298 299
		omapi_object_reference
			((omapi_object_t **)&omapi_registered_messages -> prev,
300
			 (omapi_object_t *)m, MDL);
Ted Lemon's avatar
Ted Lemon committed
301
		omapi_object_dereference
302
			((omapi_object_t **)&omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
303 304 305
	}
	omapi_object_reference
		((omapi_object_t **)&omapi_registered_messages,
306
		 (omapi_object_t *)m, MDL);
Ted Lemon's avatar
Ted Lemon committed
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
	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
326 327
					(omapi_object_t *)m -> next, MDL);
		omapi_object_dereference ((omapi_object_t **)&m -> next, MDL);
Ted Lemon's avatar
Ted Lemon committed
328 329 330 331
	}
	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
332 333
					(omapi_object_t *)m -> prev, MDL);
		omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL);
Ted Lemon's avatar
Ted Lemon committed
334 335
		if (tmp -> next)
			omapi_object_dereference
Ted Lemon's avatar
Ted Lemon committed
336
				((omapi_object_t **)&tmp -> next, MDL);
Ted Lemon's avatar
Ted Lemon committed
337 338 339
		if (n)
			omapi_object_reference
				((omapi_object_t **)&tmp -> next,
Ted Lemon's avatar
Ted Lemon committed
340 341
				 (omapi_object_t *)n, MDL);
		omapi_object_dereference ((omapi_object_t **)&tmp, MDL);
Ted Lemon's avatar
Ted Lemon committed
342 343
	} else {
		omapi_object_dereference
Ted Lemon's avatar
Ted Lemon committed
344
			((omapi_object_t **)&omapi_registered_messages, MDL);
Ted Lemon's avatar
Ted Lemon committed
345 346 347
		if (n)
			omapi_object_reference
				((omapi_object_t **)&omapi_registered_messages,
Ted Lemon's avatar
Ted Lemon committed
348
				 (omapi_object_t *)n, MDL);
Ted Lemon's avatar
Ted Lemon committed
349 350
	}
	if (n)
Ted Lemon's avatar
Ted Lemon committed
351
		omapi_object_dereference ((omapi_object_t **)&n, MDL);
Ted Lemon's avatar
Ted Lemon committed
352 353
	return ISC_R_SUCCESS;
}
354 355 356 357 358

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
359
	omapi_value_t *tv = (omapi_value_t *)0;
360 361
	unsigned long create, update, exclusive;
	unsigned long wsi;
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
	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
378 379
	} else
		m = (omapi_message_object_t *)0;
380 381 382 383

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

		/* Get the type of the requested object, if one was
		   specified. */
Ted Lemon's avatar
Ted Lemon committed
391
		status = omapi_get_value_str (mo, (omapi_object_t *)0,
392 393 394 395 396 397 398 399 400 401 402 403
					      "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
404
			omapi_value_dereference (&tv, MDL);
405 406

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

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

		/* Get the exclusive flag. */
Ted Lemon's avatar
Ted Lemon committed
439
		status = omapi_get_value_str (mo,
440 441 442
					      (omapi_object_t *)0,
					      "exclusive", &tv);
		if (status == ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
443
			status = omapi_get_int_value (&exclusive, tv -> value);
Ted Lemon's avatar
Ted Lemon committed
444
			omapi_value_dereference (&tv, MDL);
445
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
446 447 448
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
449 450 451 452 453 454 455 456 457
					 "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
458 459 460
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 ISC_R_INVALIDARG, message -> id,
461 462 463 464 465 466 467 468
					 "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
469 470 471
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_NOTIMPLEMENTED, message -> id,
472 473
				 "unsearchable object type");
		}
474 475 476 477 478 479 480

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

484 485 486
		if (status != ISC_R_SUCCESS &&
		    status != ISC_R_NOTFOUND &&
		    status != ISC_R_NOKEYS) {
Ted Lemon's avatar
Ted Lemon committed
487 488 489
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 status, message -> id,
490 491 492 493 494 495
				 "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
496 497 498
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_NOTFOUND, message -> id,
499 500 501 502 503 504 505
				 "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
506
			omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
507 508 509
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 ISC_R_EXISTS, message -> id,
510 511 512 513 514
				 "specified object already exists");
		}

		/* If we're creating the object, do it now. */
		if (!object) {
Ted Lemon's avatar
Ted Lemon committed
515 516 517
			status = omapi_object_create (&object,
						      (omapi_object_t *)0,
						      type);
518
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
519 520 521
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
522 523 524 525 526 527 528
					 "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
529
						      (omapi_object_t *)0,
530
						      message -> object,
Ted Lemon's avatar
Ted Lemon committed
531
						      message -> h);
532
			if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
533
				omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
534 535 536
				return omapi_protocol_send_status
					(po, (omapi_object_t *)0,
					 status, message -> id,
537 538 539 540 541 542 543 544 545 546
					 "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
547
		status = omapi_handle_lookup (&object, message -> h);
548
		if (status != ISC_R_SUCCESS) {
Ted Lemon's avatar
Ted Lemon committed
549 550 551
			return omapi_protocol_send_status
				(po, (omapi_object_t *)0,
				 status, message -> id,
552 553 554
				 "no matching handle");
		}
	      send:		
Ted Lemon's avatar
Ted Lemon committed
555 556
		status = omapi_protocol_send_update (po, (omapi_object_t *)0,
						     message -> id, object);
Ted Lemon's avatar
Ted Lemon committed
557
		omapi_object_dereference (&object, MDL);
Ted Lemon's avatar
Ted Lemon committed
558
		return status;
559 560

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

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

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

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

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

Ted Lemon's avatar
Ted Lemon committed
622 623 624 625 626
		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
627
			omapi_value_dereference (&tv, MDL);
628
		return ISC_R_SUCCESS;
629 630

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

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

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

		return omapi_protocol_send_status (po, (omapi_object_t *)0,
						   status, message -> id,
						   (char *)0);
652 653 654
	}
	return ISC_R_NOTIMPLEMENTED;
}