xref: /minix3/external/bsd/dhcp/dist/common/tree.c (revision d56f51ea7d8b9045e5c8e2028422523d3f9a5840)
1 /*	$NetBSD: tree.c,v 1.1.1.3 2014/07/12 11:57:48 spz Exp $	*/
2 /* tree.c
3 
4    Routines for manipulating parse trees... */
5 
6 /*
7  * Copyright (c) 2011-2014 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
9  * Copyright (c) 1995-2003 by Internet Software Consortium
10  *
11  * Permission to use, copy, modify, and distribute this software for any
12  * purpose with or without fee is hereby granted, provided that the above
13  * copyright notice and this permission notice appear in all copies.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
18  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  *   Internet Systems Consortium, Inc.
24  *   950 Charter Street
25  *   Redwood City, CA 94063
26  *   <info@isc.org>
27  *   https://www.isc.org/
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: tree.c,v 1.1.1.3 2014/07/12 11:57:48 spz Exp $");
33 
34 #include "dhcpd.h"
35 #include <omapip/omapip_p.h>
36 #include <ctype.h>
37 #include <sys/wait.h>
38 
39 #ifdef HAVE_REGEX_H
40 # include <regex.h>
41 #endif
42 
43 struct binding_scope *global_scope;
44 
45 static int do_host_lookup (struct data_string *, struct dns_host_entry *);
46 
47 #define DS_SPRINTF_SIZE 128
48 
49 /*
50  * If we are using a data_string structure to hold a NUL-terminated
51  * ASCII string, this function can be used to append a printf-formatted
52  * string to the end of it. The data_string structure will be resized to
53  * be big enough to hold the new string.
54  *
55  * If the append works, then 1 is returned.
56  *
57  * If it is not possible to allocate a buffer big enough to hold the
58  * new value, then the old data_string is unchanged, and 0 is returned.
59  */
60 int
61 data_string_sprintfa(struct data_string *ds, const char *fmt, ...) {
62 	va_list args;
63 	int cur_strlen;
64 	int max;
65 	int vsnprintf_ret;
66 	int new_len;
67 	struct buffer *tmp_buffer;
68 
69 	/*
70 	 * If the data_string is empty, then initialize it.
71 	 */
72 	if (ds->data == NULL) {
73 		/* INSIST(ds.buffer == NULL); */
74 		if (!buffer_allocate(&ds->buffer, DS_SPRINTF_SIZE, MDL)) {
75 			return 0;
76 		}
77 		ds->data = ds->buffer->data;
78 		ds->len = DS_SPRINTF_SIZE;
79 		*((char *)ds->data) = '\0';
80 	}
81 
82 	/*
83 	 * Get the length of the string, and figure out how much space
84 	 * is left.
85 	 */
86 	cur_strlen = strlen((char *)ds->data);
87 	max = ds->len - cur_strlen;
88 
89 	/*
90 	 * Use vsnprintf(), which won't write past our space, but will
91 	 * tell us how much space it wants.
92 	 */
93 	va_start(args, fmt);
94 	vsnprintf_ret = vsnprintf((char *)ds->data+cur_strlen, max, fmt, args);
95 	va_end(args);
96 	/* INSIST(vsnprintf_ret >= 0); */
97 
98 	/*
99 	 * If our buffer is not big enough, we need a new buffer.
100 	 */
101 	if (vsnprintf_ret >= max) {
102 		/*
103 		 * Figure out a size big enough.
104 		 */
105 		new_len = ds->len * 2;
106 		while (new_len <= cur_strlen + vsnprintf_ret) {
107 			new_len *= 2;
108 		}
109 
110 		/*
111 		 * Create a new buffer and fill it.
112 		 */
113 		tmp_buffer = NULL;
114 		if (!buffer_allocate(&tmp_buffer, new_len, MDL)) {
115 			/*
116 			 * If we can't create a big enough buffer,
117 			 * we should remove any truncated output that we had.
118 			 */
119 			*((char *)ds->data+cur_strlen) = '\0';
120 			va_end(args);
121 			return 0;
122 		}
123 		memcpy(tmp_buffer->data, ds->data, cur_strlen);
124 
125 		/* Rerun the vsprintf. */
126 		va_start(args, fmt);
127 		vsprintf((char *)tmp_buffer->data + cur_strlen, fmt, args);
128 		va_end(args);
129 
130 		/*
131 		 * Replace our old buffer with the new buffer.
132 		 */
133 		buffer_dereference(&ds->buffer, MDL);
134 		buffer_reference(&ds->buffer, tmp_buffer, MDL);
135 		buffer_dereference(&tmp_buffer, MDL);
136 		ds->data = ds->buffer->data;
137 		ds->len = new_len;
138 	}
139 	return 1;
140 }
141 
142 pair cons (car, cdr)
143 	caddr_t car;
144 	pair cdr;
145 {
146 	pair foo = (pair)dmalloc (sizeof *foo, MDL);
147 	if (!foo)
148 		log_fatal ("no memory for cons.");
149 	foo -> car = car;
150 	foo -> cdr = cdr;
151 	return foo;
152 }
153 
154 int make_const_option_cache (oc, buffer, data, len, option, file, line)
155 	struct option_cache **oc;
156 	struct buffer **buffer;
157 	u_int8_t *data;
158 	unsigned len;
159 	struct option *option;
160 	const char *file;
161 	int line;
162 {
163 	struct buffer *bp;
164 
165 	if (buffer) {
166 		bp = *buffer;
167 		*buffer = 0;
168 	} else {
169 		bp = (struct buffer *)0;
170 		if (!buffer_allocate (&bp, len, file, line)) {
171 			log_error ("%s(%d): can't allocate buffer.",
172 				   file, line);
173 			return 0;
174 		}
175 	}
176 
177 	if (!option_cache_allocate (oc, file, line)) {
178 		log_error ("%s(%d): can't allocate option cache.", file, line);
179 		buffer_dereference (&bp, file, line);
180 		return 0;
181 	}
182 
183 	(*oc) -> data.len = len;
184 	(*oc) -> data.buffer = bp;
185 	(*oc) -> data.data = &bp -> data [0];
186 	(*oc) -> data.terminated = 0;
187 	if (data)
188 		memcpy (&bp -> data [0], data, len);
189 	option_reference(&((*oc)->option), option, MDL);
190 	return 1;
191 }
192 
193 int make_host_lookup (expr, name)
194 	struct expression **expr;
195 	const char *name;
196 {
197 	if (!expression_allocate (expr, MDL)) {
198 		log_error ("No memory for host lookup tree node.");
199 		return 0;
200 	}
201 	(*expr) -> op = expr_host_lookup;
202 	if (!enter_dns_host (&((*expr) -> data.host_lookup), name)) {
203 		expression_dereference (expr, MDL);
204 		return 0;
205 	}
206 	return 1;
207 }
208 
209 int enter_dns_host (dh, name)
210 	struct dns_host_entry **dh;
211 	const char *name;
212 {
213 	/* XXX This should really keep a hash table of hostnames
214 	   XXX and just add a new reference to a hostname that
215 	   XXX already exists, if possible, rather than creating
216 	   XXX a new structure. */
217 	if (!dns_host_entry_allocate (dh, name, MDL)) {
218 		log_error ("Can't allocate space for new host.");
219 		return 0;
220 	}
221 	return 1;
222 }
223 
224 int make_const_data (struct expression **expr, const unsigned char *data,
225 		     unsigned len, int terminated, int allocate,
226 		     const char *file, int line)
227 {
228 	struct expression *nt;
229 
230 	if (!expression_allocate (expr, file, line)) {
231 		log_error ("No memory for make_const_data tree node.");
232 		return 0;
233 	}
234 	nt = *expr;
235 
236 	if (len) {
237 		if (allocate) {
238 			if (!buffer_allocate (&nt -> data.const_data.buffer,
239 					      len + terminated, file, line)) {
240 				log_error ("Can't allocate const_data buffer");
241 				expression_dereference (expr, file, line);
242 				return 0;
243 			}
244 			nt -> data.const_data.data =
245 				&nt -> data.const_data.buffer -> data [0];
246 			memcpy (nt -> data.const_data.buffer -> data,
247 				data, len + terminated);
248 		} else
249 			nt -> data.const_data.data = data;
250 		nt -> data.const_data.terminated = terminated;
251 	} else
252 		nt -> data.const_data.data = 0;
253 
254 	nt -> op = expr_const_data;
255 	nt -> data.const_data.len = len;
256 	return 1;
257 }
258 
259 int make_const_int (expr, val)
260 	struct expression **expr;
261 	unsigned long val;
262 {
263 	if (!expression_allocate (expr, MDL)) {
264 		log_error ("No memory for make_const_int tree node.");
265 		return 0;
266 	}
267 
268 	(*expr) -> op = expr_const_int;
269 	(*expr) -> data.const_int = val;
270 	return 1;
271 }
272 
273 int make_concat (expr, left, right)
274 	struct expression **expr;
275 	struct expression *left, *right;
276 {
277 	/* If we're concatenating a null tree to a non-null tree, just
278 	   return the non-null tree; if both trees are null, return
279 	   a null tree. */
280 	if (!left) {
281 		if (!right)
282 			return 0;
283 		expression_reference (expr, right, MDL);
284 		return 1;
285 	}
286 	if (!right) {
287 		expression_reference (expr, left, MDL);
288 		return 1;
289 	}
290 
291 	/* Otherwise, allocate a new node to concatenate the two. */
292 	if (!expression_allocate (expr, MDL)) {
293 		log_error ("No memory for concatenation expression node.");
294 		return 0;
295 	}
296 
297 	(*expr) -> op = expr_concat;
298 	expression_reference (&(*expr) -> data.concat [0], left, MDL);
299 	expression_reference (&(*expr) -> data.concat [1], right, MDL);
300 	return 1;
301 }
302 
303 int make_encapsulation (expr, name)
304 	struct expression **expr;
305 	struct data_string *name;
306 {
307 	/* Allocate a new node to store the encapsulation. */
308 	if (!expression_allocate (expr, MDL)) {
309 		log_error ("No memory for encapsulation expression node.");
310 		return 0;
311 	}
312 
313 	(*expr) -> op = expr_encapsulate;
314 	data_string_copy (&(*expr) -> data.encapsulate, name, MDL);
315 	return 1;
316 }
317 
318 int make_substring (new, expr, offset, length)
319 	struct expression **new;
320 	struct expression *expr;
321 	struct expression *offset;
322 	struct expression *length;
323 {
324 	/* Allocate an expression node to compute the substring. */
325 	if (!expression_allocate (new, MDL)) {
326 		log_error ("no memory for substring expression.");
327 		return 0;
328 	}
329 	(*new) -> op = expr_substring;
330 	expression_reference (&(*new) -> data.substring.expr, expr, MDL);
331 	expression_reference (&(*new) -> data.substring.offset, offset, MDL);
332 	expression_reference (&(*new) -> data.substring.len, length, MDL);
333 	return 1;
334 }
335 
336 int make_limit (new, expr, limit)
337 	struct expression **new;
338 	struct expression *expr;
339 	int limit;
340 {
341 	/* Allocate a node to enforce a limit on evaluation. */
342 	if (!expression_allocate (new, MDL))
343 		log_error ("no memory for limit expression");
344 	(*new) -> op = expr_substring;
345 	expression_reference (&(*new) -> data.substring.expr, expr, MDL);
346 
347 	/* Offset is a constant 0. */
348 	if (!expression_allocate (&(*new) -> data.substring.offset, MDL)) {
349 		log_error ("no memory for limit offset expression");
350 		expression_dereference (new, MDL);
351 		return 0;
352 	}
353 	(*new) -> data.substring.offset -> op = expr_const_int;
354 	(*new) -> data.substring.offset -> data.const_int = 0;
355 
356 	/* Length is a constant: the specified limit. */
357 	if (!expression_allocate (&(*new) -> data.substring.len, MDL)) {
358 		log_error ("no memory for limit length expression");
359 		expression_dereference (new, MDL);
360 		return 0;
361 	}
362 	(*new) -> data.substring.len -> op = expr_const_int;
363 	(*new) -> data.substring.len -> data.const_int = limit;
364 
365 	return 1;
366 }
367 
368 int option_cache (struct option_cache **oc, struct data_string *dp,
369 		  struct expression *expr, struct option *option,
370 		  const char *file, int line)
371 {
372 	if (!option_cache_allocate (oc, file, line))
373 		return 0;
374 	if (dp)
375 		data_string_copy (&(*oc) -> data, dp, file, line);
376 	if (expr)
377 		expression_reference (&(*oc) -> expression, expr, file, line);
378 	option_reference(&(*oc)->option, option, MDL);
379 	return 1;
380 }
381 
382 int make_let (result, name)
383 	struct executable_statement **result;
384 	const char *name;
385 {
386 	if (!(executable_statement_allocate (result, MDL)))
387 		return 0;
388 
389 	(*result) -> op = let_statement;
390 	(*result) -> data.let.name = dmalloc (strlen (name) + 1, MDL);
391 	if (!(*result) -> data.let.name) {
392 		executable_statement_dereference (result, MDL);
393 		return 0;
394 	}
395 	strcpy ((*result) -> data.let.name, name);
396 	return 1;
397 }
398 
399 static int do_host_lookup (result, dns)
400 	struct data_string *result;
401 	struct dns_host_entry *dns;
402 {
403 	struct hostent *h;
404 	unsigned i, count;
405 	unsigned new_len;
406 
407 #ifdef DEBUG_EVAL
408 	log_debug ("time: now = %d  dns = %d  diff = %d",
409 	       cur_time, dns -> timeout, cur_time - dns -> timeout);
410 #endif
411 
412 	/* If the record hasn't timed out, just copy the data and return. */
413 	if (cur_time <= dns -> timeout) {
414 #ifdef DEBUG_EVAL
415 		log_debug ("easy copy: %d %s",
416 		       dns -> data.len,
417 		       (dns -> data.len > 4
418 			? inet_ntoa (*(struct in_addr *)(dns -> data.data))
419 			: 0));
420 #endif
421 		data_string_copy (result, &dns -> data, MDL);
422 		return 1;
423 	}
424 #ifdef DEBUG_EVAL
425 	log_debug ("Looking up %s", dns -> hostname);
426 #endif
427 
428 	/* Otherwise, look it up... */
429 	h = gethostbyname (dns -> hostname);
430 	if (!h) {
431 #ifndef NO_H_ERRNO
432 		switch (h_errno) {
433 		      case HOST_NOT_FOUND:
434 #endif
435 			log_error ("%s: host unknown.", dns -> hostname);
436 #ifndef NO_H_ERRNO
437 			break;
438 		      case TRY_AGAIN:
439 			log_error ("%s: temporary name server failure",
440 				   dns -> hostname);
441 			break;
442 		      case NO_RECOVERY:
443 			log_error ("%s: name server failed", dns -> hostname);
444 			break;
445 		      case NO_DATA:
446 			log_error ("%s: no A record associated with address",
447 				   dns -> hostname);
448 		}
449 #endif /* !NO_H_ERRNO */
450 
451 		/* Okay to try again after a minute. */
452 		dns -> timeout = cur_time + 60;
453 		data_string_forget (&dns -> data, MDL);
454 		return 0;
455 	}
456 
457 #ifdef DEBUG_EVAL
458 	log_debug ("Lookup succeeded; first address is %s",
459 	       inet_ntoa (h -> h_addr_list [0]));
460 #endif
461 
462 	/* Count the number of addresses we got... */
463 	for (count = 0; h -> h_addr_list [count]; count++)
464 		;
465 
466 	/* Dereference the old data, if any. */
467 	data_string_forget (&dns -> data, MDL);
468 
469 	/* Do we need to allocate more memory? */
470 	new_len = count * h -> h_length;
471 	if (!buffer_allocate (&dns -> data.buffer, new_len, MDL))
472 	{
473 		log_error ("No memory for %s.", dns -> hostname);
474 		return 0;
475 	}
476 
477 	dns -> data.data = &dns -> data.buffer -> data [0];
478 	dns -> data.len = new_len;
479 	dns -> data.terminated = 0;
480 
481 	/* Addresses are conveniently stored one to the buffer, so we
482 	   have to copy them out one at a time... :'( */
483 	for (i = 0; i < count; i++) {
484 		memcpy (&dns -> data.buffer -> data [h -> h_length * i],
485 			h -> h_addr_list [i], (unsigned)(h -> h_length));
486 	}
487 #ifdef DEBUG_EVAL
488 	log_debug ("dns -> data: %x  h -> h_addr_list [0]: %x",
489 		   *(int *)(dns -> buffer), h -> h_addr_list [0]);
490 #endif
491 
492 	/* XXX Set the timeout for an hour from now.
493 	   XXX This should really use the time on the DNS reply. */
494 	dns -> timeout = cur_time + 3600;
495 
496 #ifdef DEBUG_EVAL
497 	log_debug ("hard copy: %d %s", dns -> data.len,
498 	       (dns -> data.len > 4
499 		? inet_ntoa (*(struct in_addr *)(dns -> data.data)) : 0));
500 #endif
501 	data_string_copy (result, &dns -> data, MDL);
502 	return 1;
503 }
504 
505 int evaluate_expression (result, packet, lease, client_state,
506 			 in_options, cfg_options, scope, expr, file, line)
507 	struct binding_value **result;
508 	struct packet *packet;
509 	struct lease *lease;
510 	struct client_state *client_state;
511 	struct option_state *in_options;
512 	struct option_state *cfg_options;
513 	struct binding_scope **scope;
514 	struct expression *expr;
515 	const char *file;
516 	int line;
517 {
518 	struct binding_value *bv;
519 	int status;
520 	struct binding *binding;
521 
522 	bv = (struct binding_value *)0;
523 
524 	if (expr -> op == expr_variable_reference) {
525 		if (!scope || !*scope)
526 			return 0;
527 
528 		binding = find_binding (*scope, expr -> data.variable);
529 
530 		if (binding && binding -> value) {
531 			if (result)
532 				binding_value_reference (result,
533 							 binding -> value,
534 							 file, line);
535 			return 1;
536 		} else
537 			return 0;
538 	} else if (expr -> op == expr_funcall) {
539 		struct string_list *s;
540 		struct expression *arg;
541 		struct binding_scope *ns;
542 		struct binding *nb;
543 
544 		if (!scope || !*scope) {
545 			log_error ("%s: no such function.",
546 				   expr -> data.funcall.name);
547 			return 0;
548 		}
549 
550 		binding = find_binding (*scope, expr -> data.funcall.name);
551 
552 		if (!binding || !binding -> value) {
553 			log_error ("%s: no such function.",
554 				   expr -> data.funcall.name);
555 			return 0;
556 		}
557 		if (binding -> value -> type != binding_function) {
558 			log_error ("%s: not a function.",
559 				   expr -> data.funcall.name);
560 			return 0;
561 		}
562 
563 		/* Create a new binding scope in which to define
564 		   the arguments to the function. */
565 		ns = (struct binding_scope *)0;
566 		if (!binding_scope_allocate (&ns, MDL)) {
567 			log_error ("%s: can't allocate argument scope.",
568 				   expr -> data.funcall.name);
569 			return 0;
570 		}
571 
572 		arg = expr -> data.funcall.arglist;
573 		s = binding -> value -> value.fundef -> args;
574 		while (arg && s) {
575 			nb = dmalloc (sizeof *nb, MDL);
576 			if (!nb) {
577 			      blb:
578 				binding_scope_dereference (&ns, MDL);
579 				return 0;
580 			} else {
581 				memset (nb, 0, sizeof *nb);
582 				nb -> name = dmalloc (strlen (s -> string) + 1,
583 						      MDL);
584 				if (nb -> name)
585 					strcpy (nb -> name, s -> string);
586 				else {
587 					dfree (nb, MDL);
588 					goto blb;
589 				}
590 			}
591 			evaluate_expression (&nb -> value, packet, lease,
592 					     client_state,
593 					     in_options, cfg_options, scope,
594 					     arg -> data.arg.val, file, line);
595 			nb -> next = ns -> bindings;
596 			ns -> bindings = nb;
597 			arg = arg -> data.arg.next;
598 			s = s -> next;
599 		}
600 		if (arg) {
601 			log_error ("%s: too many arguments.",
602 				   expr -> data.funcall.name);
603 			binding_scope_dereference (&ns, MDL);
604 			return 0;
605 		}
606 		if (s) {
607 			log_error ("%s: too few arguments.",
608 				   expr -> data.funcall.name);
609 			binding_scope_dereference (&ns, MDL);
610 			return 0;
611 		}
612 
613 		if (scope && *scope)
614 			binding_scope_reference (&ns -> outer, *scope, MDL);
615 
616 		status = (execute_statements
617 			  (&bv, packet,
618 			   lease, client_state, in_options, cfg_options, &ns,
619 			   binding->value->value.fundef->statements, NULL));
620 		binding_scope_dereference (&ns, MDL);
621 
622 		if (!bv)
623 			return 1;
624         } else if (is_boolean_expression (expr)) {
625 		if (!binding_value_allocate (&bv, MDL))
626 			return 0;
627 		bv -> type = binding_boolean;
628 		status = (evaluate_boolean_expression
629 			  (&bv -> value.boolean, packet, lease, client_state,
630 			   in_options, cfg_options, scope, expr));
631 	} else if (is_numeric_expression (expr)) {
632 		if (!binding_value_allocate (&bv, MDL))
633 			return 0;
634 		bv -> type = binding_numeric;
635 		status = (evaluate_numeric_expression
636 			  (&bv -> value.intval, packet, lease, client_state,
637 			   in_options, cfg_options, scope, expr));
638 	} else if (is_data_expression  (expr)) {
639 		if (!binding_value_allocate (&bv, MDL))
640 			return 0;
641 		bv -> type = binding_data;
642 		status = (evaluate_data_expression
643 			  (&bv -> value.data, packet, lease, client_state,
644 			   in_options, cfg_options, scope, expr, MDL));
645 	} else {
646 		log_error ("%s: invalid expression type: %d",
647 			   "evaluate_expression", expr -> op);
648 		return 0;
649 	}
650 	if (result && status)
651 		binding_value_reference (result, bv, file, line);
652 	binding_value_dereference (&bv, MDL);
653 
654 	return status;
655 }
656 
657 int binding_value_dereference (struct binding_value **v,
658 			       const char *file, int line)
659 {
660 	struct binding_value *bv = *v;
661 
662 	*v = (struct binding_value *)0;
663 
664 	/* Decrement the reference count.   If it's nonzero, we're
665 	   done. */
666 	--(bv -> refcnt);
667 	rc_register (file, line, v, bv, bv -> refcnt, 1, RC_MISC);
668 	if (bv -> refcnt > 0)
669 		return 1;
670 	if (bv -> refcnt < 0) {
671 		log_error ("%s(%d): negative refcnt!", file, line);
672 #if defined (DEBUG_RC_HISTORY)
673 		dump_rc_history (bv);
674 #endif
675 #if defined (POINTER_DEBUG)
676 		abort ();
677 #else
678 		return 0;
679 #endif
680 	}
681 
682 	switch (bv -> type) {
683 	      case binding_boolean:
684 	      case binding_numeric:
685 		break;
686 	      case binding_data:
687 		if (bv -> value.data.buffer)
688 			data_string_forget (&bv -> value.data, file, line);
689 		break;
690 	      default:
691 		log_error ("%s(%d): invalid binding type: %d",
692 			   file, line, bv -> type);
693 		return 0;
694 	}
695 	free_binding_value(bv, file, line);
696 	return 1;
697 }
698 
699 int evaluate_boolean_expression (result, packet, lease, client_state,
700 				 in_options, cfg_options, scope, expr)
701 	int *result;
702 	struct packet *packet;
703 	struct lease *lease;
704 	struct client_state *client_state;
705 	struct option_state *in_options;
706 	struct option_state *cfg_options;
707 	struct binding_scope **scope;
708 	struct expression *expr;
709 {
710 	struct data_string left, right;
711 	int bleft, bright;
712 	int sleft, sright;
713 	struct binding *binding;
714 	struct binding_value *bv, *obv;
715 #ifdef HAVE_REGEX_H
716 	int regflags = REG_EXTENDED | REG_NOSUB;
717 	regex_t re;
718 #endif
719 
720 	switch (expr -> op) {
721 	      case expr_check:
722 		*result = check_collection (packet, lease,
723 					    expr -> data.check);
724 #if defined (DEBUG_EXPRESSIONS)
725 		log_debug ("bool: check (%s) returns %s",
726 			   expr -> data.check -> name,
727 			   *result ? "true" : "false");
728 #endif
729 		return 1;
730 
731 	      case expr_equal:
732 	      case expr_not_equal:
733 		bv = obv = (struct binding_value *)0;
734 		sleft = evaluate_expression (&bv, packet, lease, client_state,
735 					     in_options, cfg_options, scope,
736 					     expr -> data.equal [0], MDL);
737 		sright = evaluate_expression (&obv, packet, lease,
738 					      client_state, in_options,
739 					      cfg_options, scope,
740 					      expr -> data.equal [1], MDL);
741 		if (sleft && sright) {
742 		    if (bv -> type != obv -> type)
743 			*result = expr -> op == expr_not_equal;
744 		    else {
745 			switch (obv -> type) {
746 			  case binding_boolean:
747 			    if (bv -> value.boolean == obv -> value.boolean)
748 				*result = expr -> op == expr_equal;
749 			    else
750 				*result = expr -> op == expr_not_equal;
751 			    break;
752 
753 			  case binding_data:
754 			    if ((bv -> value.data.len ==
755 				 obv -> value.data.len) &&
756 				!memcmp (bv -> value.data.data,
757 					 obv -> value.data.data,
758 					 obv -> value.data.len))
759 				*result = expr -> op == expr_equal;
760 			    else
761 				*result = expr -> op == expr_not_equal;
762 			    break;
763 
764 			  case binding_numeric:
765 			    if (bv -> value.intval == obv -> value.intval)
766 				*result = expr -> op == expr_equal;
767 			    else
768 				*result = expr -> op == expr_not_equal;
769 			    break;
770 
771 			  case binding_function:
772 			    if (bv -> value.fundef == obv -> value.fundef)
773 				*result = expr -> op == expr_equal;
774 			    else
775 				*result = expr -> op == expr_not_equal;
776 			    break;
777 			  default:
778 			    *result = expr -> op == expr_not_equal;
779 			    break;
780 			}
781 		    }
782 		} else if (!sleft && !sright)
783 		    *result = expr -> op == expr_equal;
784 		else
785 		    *result = expr -> op == expr_not_equal;
786 
787 #if defined (DEBUG_EXPRESSIONS)
788 		log_debug ("bool: %sequal = %s",
789 			   expr -> op == expr_not_equal ? "not" : "",
790 			   (*result ? "true" : "false"));
791 #endif
792 		if (sleft)
793 			binding_value_dereference (&bv, MDL);
794 		if (sright)
795 			binding_value_dereference (&obv, MDL);
796 		return 1;
797 
798 	      case expr_iregex_match:
799 #ifdef HAVE_REGEX_H
800 		regflags |= REG_ICASE;
801 #endif
802 		/* FALL THROUGH */
803 	      case expr_regex_match:
804 #ifdef HAVE_REGEX_H
805 		memset(&left, 0, sizeof left);
806 		bleft = evaluate_data_expression(&left, packet, lease,
807 						 client_state,
808 						 in_options, cfg_options,
809 						 scope,
810 						 expr->data.equal[0], MDL);
811 		memset(&right, 0, sizeof right);
812 		bright = evaluate_data_expression(&right, packet, lease,
813 						  client_state,
814 						  in_options, cfg_options,
815 						  scope,
816 						  expr->data.equal[1], MDL);
817 
818 		*result = 0;
819 		memset(&re, 0, sizeof(re));
820 		if (bleft && bright &&
821 		    (left.data != NULL) && (right.data != NULL) &&
822         	    (regcomp(&re, (char *)right.data, regflags) == 0) &&
823 		    (regexec(&re, (char *)left.data, (size_t)0, NULL, 0) == 0))
824 				*result = 1;
825 
826 #if defined (DEBUG_EXPRESSIONS)
827 		log_debug("bool: %s ~= %s yields %s",
828 			  bleft ? print_hex_1(left.len, left.data, 20)
829 				: "NULL",
830 			  bright ? print_hex_2 (right.len, right.data, 20)
831 				 : "NULL",
832 			  *result ? "true" : "false");
833 #endif
834 
835 		if (bleft)
836 			data_string_forget(&left, MDL);
837 		if (bright)
838 			data_string_forget(&right, MDL);
839 
840 		regfree(&re);
841 
842 		/*
843 		 * If we have bleft and bright then we have a good
844 		 * syntax, otherwise not.
845 		 *
846 		 * XXX: we don't warn on invalid regular expression
847 		 *      syntax, should we?
848 		 */
849 		return bleft && bright;
850 #else
851 		/* It shouldn't be possible to configure a regex operator
852 		 * when there's no support.
853 		 */
854 		log_fatal("Impossible condition at %s:%d.", MDL);
855 		break;
856 #endif
857 
858 	      case expr_and:
859 		sleft = evaluate_boolean_expression (&bleft, packet, lease,
860 						     client_state,
861 						     in_options, cfg_options,
862 						     scope,
863 						     expr -> data.and [0]);
864 		if (sleft && bleft)
865 			sright = evaluate_boolean_expression
866 				(&bright, packet, lease, client_state,
867 				 in_options, cfg_options,
868 				 scope, expr -> data.and [1]);
869 		else
870 			sright = bright = 0;
871 
872 #if defined (DEBUG_EXPRESSIONS)
873 		log_debug ("bool: and (%s, %s) = %s",
874 		      sleft ? (bleft ? "true" : "false") : "NULL",
875 		      sright ? (bright ? "true" : "false") : "NULL",
876 		      ((sleft && sright)
877 		       ? (bleft && bright ? "true" : "false") : "NULL"));
878 #endif
879 		if (sleft && sright) {
880 			*result = bleft && bright;
881 			return 1;
882 		}
883 		return 0;
884 
885 	      case expr_or:
886 		bleft = bright = 0;
887 		sleft = evaluate_boolean_expression (&bleft, packet, lease,
888 						     client_state,
889 						     in_options, cfg_options,
890 						     scope,
891 						     expr -> data.or [0]);
892 		if (!sleft || !bleft)
893 			sright = evaluate_boolean_expression
894 				(&bright, packet, lease, client_state,
895 				 in_options, cfg_options,
896 				 scope, expr -> data.or [1]);
897 		else
898 			sright = 0;
899 #if defined (DEBUG_EXPRESSIONS)
900 		log_debug ("bool: or (%s, %s) = %s",
901 		      sleft ? (bleft ? "true" : "false") : "NULL",
902 		      sright ? (bright ? "true" : "false") : "NULL",
903 		      ((sleft || sright)
904 		       ? (bleft || bright ? "true" : "false") : "NULL"));
905 #endif
906 		if (sleft || sright) {
907 			*result = bleft || bright;
908 			return 1;
909 		}
910 		return 0;
911 
912 	      case expr_not:
913 		sleft = evaluate_boolean_expression(&bleft, packet, lease,
914 						    client_state,
915 						    in_options, cfg_options,
916 						    scope,
917 						    expr->data.not);
918 #if defined (DEBUG_EXPRESSIONS)
919 		log_debug("bool: not (%s) = %s",
920 			  sleft ? (bleft ? "true" : "false") : "NULL",
921 			  sleft ? (!bleft ? "true" : "false") : "NULL");
922 #endif
923 		if (sleft) {
924 			*result = !bleft;
925 			return 1;
926 		}
927 		return 0;
928 
929 	      case expr_exists:
930 		memset (&left, 0, sizeof left);
931 		if (!in_options ||
932 		    !get_option (&left, expr -> data.exists -> universe,
933 				 packet, lease, client_state,
934 				 in_options, cfg_options, in_options,
935 				 scope, expr -> data.exists -> code, MDL))
936 			*result = 0;
937 		else {
938 			*result = 1;
939 			data_string_forget (&left, MDL);
940 		}
941 #if defined (DEBUG_EXPRESSIONS)
942 		log_debug ("bool: exists %s.%s = %s",
943 			   expr -> data.option -> universe -> name,
944 			   expr -> data.option -> name,
945 			   *result ? "true" : "false");
946 #endif
947 		return 1;
948 
949 	      case expr_known:
950 		if (!packet) {
951 #if defined (DEBUG_EXPRESSIONS)
952 			log_debug ("bool: known = NULL");
953 #endif
954 			return 0;
955 		}
956 #if defined (DEBUG_EXPRESSIONS)
957 		log_debug ("bool: known = %s",
958 			  packet -> known ? "true" : "false");
959 #endif
960 		*result = packet -> known;
961 		return 1;
962 
963 	      case expr_static:
964 		if (!lease || !(lease -> flags & STATIC_LEASE)) {
965 #if defined (DEBUG_EXPRESSIONS)
966 			log_debug ("bool: static = false (%s %s %s %d)",
967 				   lease ? "y" : "n",
968 				   (lease && (lease -> flags & STATIC_LEASE)
969 				    ? "y" : "n"),
970 				   piaddr (lease -> ip_addr),
971 				   lease ? lease -> flags : 0);
972 #endif
973 			*result = 0;
974 			return 1;
975 		}
976 #if defined (DEBUG_EXPRESSIONS)
977 		log_debug ("bool: static = true");
978 #endif
979 		*result = 1;
980 		return 1;
981 
982 	      case expr_variable_exists:
983 		if (scope && *scope) {
984 			binding = find_binding (*scope, expr -> data.variable);
985 
986 			if (binding) {
987 				if (binding -> value)
988 					*result = 1;
989 				else
990 					*result = 0;
991 			} else
992 				*result = 0;
993 		} else
994 			*result = 0;
995 #if defined (DEBUG_EXPRESSIONS)
996 		log_debug ("boolean: %s? = %s", expr -> data.variable,
997 			   *result ? "true" : "false");
998 #endif
999 		return 1;
1000 
1001 	      case expr_variable_reference:
1002 		if (scope && *scope) {
1003 		    binding = find_binding (*scope, expr -> data.variable);
1004 
1005 		    if (binding && binding -> value) {
1006 			if (binding -> value -> type ==
1007 			    binding_boolean) {
1008 				*result = binding -> value -> value.boolean;
1009 				sleft = 1;
1010 			} else {
1011 				log_error ("binding type %d in %s.",
1012 					   binding -> value -> type,
1013 					   "evaluate_boolean_expression");
1014 				sleft = 0;
1015 			}
1016 		    } else
1017 			    sleft = 0;
1018 		} else
1019 			sleft = 0;
1020 #if defined (DEBUG_EXPRESSIONS)
1021 		log_debug ("boolean: %s = %s", expr -> data.variable,
1022 			   sleft ? (*result ? "true" : "false") : "NULL");
1023 #endif
1024 		return sleft;
1025 
1026 	      case expr_funcall:
1027 		bv = (struct binding_value *)0;
1028 		sleft = evaluate_expression (&bv, packet, lease, client_state,
1029 					  in_options, cfg_options,
1030 					  scope, expr, MDL);
1031 		if (sleft) {
1032 			if (bv -> type != binding_boolean)
1033 				log_error ("%s() returned type %d in %s.",
1034 					   expr -> data.funcall.name,
1035 					   bv -> type,
1036 					   "evaluate_boolean_expression");
1037 			else
1038 				*result = bv -> value.boolean;
1039 			binding_value_dereference (&bv, MDL);
1040 		}
1041 #if defined (DEBUG_EXPRESSIONS)
1042 		log_debug ("boolean: %s() = %s", expr -> data.funcall.name,
1043 			   sleft ? (*result ? "true" : "false") : "NULL");
1044 #endif
1045 		break;
1046 
1047 	      case expr_none:
1048 	      case expr_match:
1049 	      case expr_substring:
1050 	      case expr_suffix:
1051 	      case expr_lcase:
1052 	      case expr_ucase:
1053 	      case expr_option:
1054 	      case expr_hardware:
1055 	      case expr_const_data:
1056 	      case expr_packet:
1057 	      case expr_concat:
1058 	      case expr_encapsulate:
1059 	      case expr_host_lookup:
1060 	      case expr_encode_int8:
1061 	      case expr_encode_int16:
1062 	      case expr_encode_int32:
1063 	      case expr_binary_to_ascii:
1064 	      case expr_reverse:
1065 	      case expr_pick_first_value:
1066 	      case expr_host_decl_name:
1067 	      case expr_config_option:
1068 	      case expr_leased_address:
1069 	      case expr_null:
1070 	      case expr_filename:
1071 	      case expr_sname:
1072 	      case expr_gethostname:
1073 	      case expr_v6relay:
1074 		log_error ("Data opcode in evaluate_boolean_expression: %d",
1075 		      expr -> op);
1076 		return 0;
1077 
1078 	      case expr_extract_int8:
1079 	      case expr_extract_int16:
1080 	      case expr_extract_int32:
1081 	      case expr_const_int:
1082 	      case expr_lease_time:
1083 	      case expr_dns_transaction:
1084 	      case expr_add:
1085 	      case expr_subtract:
1086 	      case expr_multiply:
1087 	      case expr_divide:
1088 	      case expr_remainder:
1089 	      case expr_binary_and:
1090 	      case expr_binary_or:
1091 	      case expr_binary_xor:
1092 	      case expr_client_state:
1093 		log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1094 		      expr -> op);
1095 		return 0;
1096 
1097 	      case expr_ns_add:
1098 	      case expr_ns_delete:
1099 	      case expr_ns_exists:
1100 	      case expr_ns_not_exists:
1101 		log_error ("dns opcode in evaluate_boolean_expression: %d",
1102 		      expr -> op);
1103 		return 0;
1104 
1105 	      case expr_function:
1106 		log_error ("function definition in evaluate_boolean_expr");
1107 		return 0;
1108 
1109 	      case expr_arg:
1110 		break;
1111 	}
1112 
1113 	log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1114 		   expr -> op);
1115 	return 0;
1116 }
1117 
1118 int evaluate_data_expression (result, packet, lease, client_state,
1119 			      in_options, cfg_options, scope, expr, file, line)
1120 	struct data_string *result;
1121 	struct packet *packet;
1122 	struct lease *lease;
1123 	struct client_state *client_state;
1124 	struct option_state *in_options;
1125 	struct option_state *cfg_options;
1126 	struct binding_scope **scope;
1127 	struct expression *expr;
1128 	const char *file;
1129 	int line;
1130 {
1131 	struct data_string data, other;
1132 	unsigned long offset, len, i;
1133 	int s0, s1, s2, s3;
1134 	int status;
1135 	struct binding *binding;
1136 	unsigned char *s;
1137 	struct binding_value *bv;
1138 	struct packet *relay_packet;
1139 	struct option_state *relay_options;
1140 
1141 	switch (expr -> op) {
1142 		/* Extract N bytes starting at byte M of a data string. */
1143 	      case expr_substring:
1144 		memset (&data, 0, sizeof data);
1145 		s0 = evaluate_data_expression (&data, packet, lease,
1146 					       client_state,
1147 					       in_options, cfg_options, scope,
1148 					       expr -> data.substring.expr,
1149 					       MDL);
1150 
1151 		/* Evaluate the offset and length. */
1152 		s1 = evaluate_numeric_expression
1153 			(&offset, packet, lease, client_state, in_options,
1154 			 cfg_options, scope, expr -> data.substring.offset);
1155 		s2 = evaluate_numeric_expression (&len, packet, lease,
1156 						  client_state,
1157 						  in_options, cfg_options,
1158 						  scope,
1159 						  expr -> data.substring.len);
1160 
1161 		if (s0 && s1 && s2) {
1162 			/* If the offset is after end of the string,
1163 			   return an empty string.  Otherwise, do the
1164 			   adjustments and return what's left. */
1165 			if (data.len > offset) {
1166 				data_string_copy (result, &data, file, line);
1167 				result -> len -= offset;
1168 				if (result -> len > len) {
1169 					result -> len = len;
1170 					result -> terminated = 0;
1171 				}
1172 				result -> data += offset;
1173 			}
1174 			s3 = 1;
1175 		} else
1176 			s3 = 0;
1177 
1178 #if defined (DEBUG_EXPRESSIONS)
1179 		log_debug ("data: substring (%s, %s, %s) = %s",
1180 		      s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1181 		      s1 ? print_dec_1 (offset) : "NULL",
1182 		      s2 ? print_dec_2 (len) : "NULL",
1183 		      (s3 ? print_hex_2 (result -> len, result -> data, 30)
1184 		          : "NULL"));
1185 #endif
1186 		if (s0)
1187 			data_string_forget (&data, MDL);
1188 		if (s3)
1189 			return 1;
1190 		return 0;
1191 
1192 		/* Extract the last N bytes of a data string. */
1193 	      case expr_suffix:
1194 		memset (&data, 0, sizeof data);
1195 		s0 = evaluate_data_expression (&data, packet, lease,
1196 					       client_state,
1197 					       in_options, cfg_options, scope,
1198 					       expr -> data.suffix.expr, MDL);
1199 		/* Evaluate the length. */
1200 		s1 = evaluate_numeric_expression (&len, packet, lease,
1201 						  client_state,
1202 						  in_options, cfg_options,
1203 						  scope,
1204 						  expr -> data.suffix.len);
1205 		if (s0 && s1) {
1206 			data_string_copy (result, &data, file, line);
1207 
1208 			/* If we are returning the last N bytes of a
1209 			   string whose length is <= N, just return
1210 			   the string - otherwise, compute a new
1211 			   starting address and decrease the
1212 			   length. */
1213 			if (data.len > len) {
1214 				result -> data += data.len - len;
1215 				result -> len = len;
1216 			}
1217 
1218 			data_string_forget (&data, MDL);
1219 		}
1220 
1221 #if defined (DEBUG_EXPRESSIONS)
1222 		log_debug ("data: suffix (%s, %s) = %s",
1223 		      s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1224 		      s1 ? print_dec_1 (len) : "NULL",
1225 		      ((s0 && s1)
1226 		       ? print_hex_2 (result -> len, result -> data, 30)
1227 		       : "NULL"));
1228 #endif
1229 
1230 		return s0 && s1;
1231 
1232 		/* Convert string to lowercase. */
1233 	      case expr_lcase:
1234 		memset(&data, 0, sizeof data);
1235 		s0 = evaluate_data_expression(&data, packet, lease,
1236 					      client_state,
1237 					      in_options, cfg_options, scope,
1238 					      expr->data.lcase, MDL);
1239 		s1 = 0;
1240 		if (s0) {
1241 			result->len = data.len;
1242 			if (buffer_allocate(&result->buffer,
1243 					    result->len + data.terminated,
1244 					    MDL)) {
1245 				result->data = &result->buffer->data[0];
1246 				memcpy(result->buffer->data, data.data,
1247 				       data.len + data.terminated);
1248 				result->terminated = data.terminated;
1249 				s = (unsigned char *)result->data;
1250 				for (i = 0; i < result->len; i++, s++)
1251 					*s = tolower(*s);
1252 				s1 = 1;
1253 			} else {
1254 				log_error("data: lcase: no buffer memory.");
1255 			}
1256 		}
1257 
1258 #if defined (DEBUG_EXPRESSIONS)
1259 		log_debug("data: lcase (%s) = %s",
1260 			  s0 ? print_hex_1(data.len, data.data, 30) : "NULL",
1261 			  s1 ? print_hex_2(result->len, result->data, 30)
1262 			     : "NULL");
1263 #endif
1264 		if (s0)
1265 			data_string_forget(&data, MDL);
1266 		return s1;
1267 
1268 		/* Convert string to uppercase. */
1269 	      case expr_ucase:
1270 		memset(&data, 0, sizeof data);
1271 		s0 = evaluate_data_expression(&data, packet, lease,
1272 					      client_state,
1273 					      in_options, cfg_options, scope,
1274 					      expr->data.lcase, MDL);
1275 		s1 = 0;
1276 		if (s0) {
1277 			result->len = data.len;
1278 			if (buffer_allocate(&result->buffer,
1279 					    result->len + data.terminated,
1280 					    file, line)) {
1281 				result->data = &result->buffer->data[0];
1282 				memcpy(result->buffer->data, data.data,
1283 				       data.len + data.terminated);
1284 				result->terminated = data.terminated;
1285 				s = (unsigned char *)result->data;
1286 				for (i = 0; i < result->len; i++, s++)
1287 					*s = toupper(*s);
1288 				s1 = 1;
1289 			} else {
1290 				log_error("data: lcase: no buffer memory.");
1291 			}
1292 		}
1293 
1294 #if defined (DEBUG_EXPRESSIONS)
1295 		log_debug("data: ucase (%s) = %s",
1296 			  s0 ? print_hex_1(data.len, data.data, 30) : "NULL",
1297 			  s1 ? print_hex_2(result->len, result->data, 30)
1298 			     : "NULL");
1299 #endif
1300 		if (s0)
1301 			data_string_forget(&data, MDL);
1302 
1303 		 return s1;
1304 
1305 		/* Extract an option. */
1306 	      case expr_option:
1307 		if (in_options)
1308 		    s0 = get_option (result,
1309 				     expr -> data.option -> universe,
1310 				     packet, lease, client_state,
1311 				     in_options, cfg_options, in_options,
1312 				     scope, expr -> data.option -> code,
1313 				     file, line);
1314 		else
1315 			s0 = 0;
1316 
1317 #if defined (DEBUG_EXPRESSIONS)
1318 		log_debug ("data: option %s.%s = %s",
1319 		      expr -> data.option -> universe -> name,
1320 		      expr -> data.option -> name,
1321 		      s0 ? print_hex_1 (result -> len, result -> data, 60)
1322 		      : "NULL");
1323 #endif
1324 		return s0;
1325 
1326 	      case expr_config_option:
1327 		if (cfg_options)
1328 		    s0 = get_option (result,
1329 				     expr -> data.option -> universe,
1330 				     packet, lease, client_state,
1331 				     in_options, cfg_options, cfg_options,
1332 				     scope, expr -> data.option -> code,
1333 				     file, line);
1334 		else
1335 			s0 = 0;
1336 
1337 #if defined (DEBUG_EXPRESSIONS)
1338 		log_debug ("data: config-option %s.%s = %s",
1339 		      expr -> data.option -> universe -> name,
1340 		      expr -> data.option -> name,
1341 		      s0 ? print_hex_1 (result -> len, result -> data, 60)
1342 		      : "NULL");
1343 #endif
1344 		return s0;
1345 
1346 		/* Combine the hardware type and address. */
1347 	      case expr_hardware:
1348 		/* On the client, hardware is our hardware. */
1349 		if (client_state) {
1350 			memset(result, 0, sizeof(*result));
1351 			result->data = client_state->interface->hw_address.hbuf;
1352 			result->len = client_state->interface->hw_address.hlen;
1353 #if defined (DEBUG_EXPRESSIONS)
1354 			log_debug("data: hardware = %s",
1355 				  print_hex_1(result->len, result->data, 60));
1356 #endif
1357 			return (1);
1358 		}
1359 
1360 		/* The server cares about the client's hardware address,
1361 		   so only in the case where we are examining a packet or have
1362 		   a lease with a hardware address can we return anything. */
1363 
1364 		if (packet != NULL && packet->raw != NULL) {
1365 			if (packet->raw->hlen > sizeof(packet->raw->chaddr)) {
1366 				log_error("data: hardware: invalid hlen (%d)\n",
1367 					  packet->raw->hlen);
1368 				return (0);
1369 			}
1370 			result->len = packet->raw->hlen + 1;
1371 			if (buffer_allocate(&result->buffer, result->len, MDL)){
1372 				result->data = &result->buffer->data[0];
1373 				result->buffer->data[0] = packet->raw->htype;
1374 				memcpy(&result->buffer->data[1],
1375 				       packet->raw->chaddr, packet->raw->hlen);
1376 				result->terminated = 0;
1377 			} else {
1378 				log_error("data: hardware: "
1379 					  "no memory for buffer.");
1380 				return (0);
1381 			}
1382 		} else if (lease != NULL) {
1383 			result->len = lease->hardware_addr.hlen;
1384 			if (buffer_allocate(&result->buffer, result->len, MDL)){
1385 				result->data = &result->buffer->data[0];
1386 				memcpy(result->buffer->data,
1387 				       lease->hardware_addr.hbuf, result->len);
1388 				result->terminated = 0;
1389 			} else {
1390 				log_error("data: hardware: "
1391 					  "no memory for buffer.");
1392 				return (0);
1393 			}
1394 		} else {
1395 			log_error("data: hardware: no raw packet or lease "
1396 				  "is available");
1397 			return (0);
1398 		}
1399 
1400 #if defined (DEBUG_EXPRESSIONS)
1401 		log_debug("data: hardware = %s",
1402 			  print_hex_1(result->len, result->data, 60));
1403 #endif
1404 		return (1);
1405 
1406 		/* Extract part of the raw packet. */
1407 	      case expr_packet:
1408 		if (!packet || !packet -> raw) {
1409 			log_error ("data: packet: raw packet not available");
1410 			return 0;
1411 		}
1412 
1413 		s0 = evaluate_numeric_expression (&offset, packet, lease,
1414 						  client_state,
1415 						  in_options, cfg_options,
1416 						  scope,
1417 						  expr -> data.packet.offset);
1418 		s1 = evaluate_numeric_expression (&len,
1419 						  packet, lease, client_state,
1420 						  in_options, cfg_options,
1421 						  scope,
1422 						  expr -> data.packet.len);
1423 		if (s0 && s1 && offset < packet -> packet_length) {
1424 			if (offset + len > packet -> packet_length)
1425 				result -> len =
1426 					packet -> packet_length - offset;
1427 			else
1428 				result -> len = len;
1429 			if (buffer_allocate (&result -> buffer,
1430 					     result -> len, file, line)) {
1431 				result -> data = &result -> buffer -> data [0];
1432 				memcpy (result -> buffer -> data,
1433 					(((unsigned char *)(packet -> raw))
1434 					 + offset), result -> len);
1435 				result -> terminated = 0;
1436 			} else {
1437 				log_error ("data: packet: no buffer memory.");
1438 				return 0;
1439 			}
1440 			s2 = 1;
1441 		} else
1442 			s2 = 0;
1443 #if defined (DEBUG_EXPRESSIONS)
1444 		log_debug ("data: packet (%ld, %ld) = %s",
1445 		      offset, len,
1446 		      s2 ? print_hex_1 (result -> len,
1447 					result -> data, 60) : NULL);
1448 #endif
1449 		return s2;
1450 
1451 		/* The encapsulation of all defined options in an
1452 		   option space... */
1453 	      case expr_encapsulate:
1454 		if (cfg_options)
1455 			s0 = option_space_encapsulate
1456 				(result, packet, lease, client_state,
1457 				 in_options, cfg_options, scope,
1458 				 &expr -> data.encapsulate);
1459 		else
1460 			s0 = 0;
1461 
1462 #if defined (DEBUG_EXPRESSIONS)
1463 		log_debug ("data: encapsulate (%s) = %s",
1464 			  expr -> data.encapsulate.data,
1465 			  s0 ? print_hex_1 (result -> len,
1466 					    result -> data, 60) : "NULL");
1467 #endif
1468 		return s0;
1469 
1470 		/* Some constant data... */
1471 	      case expr_const_data:
1472 #if defined (DEBUG_EXPRESSIONS)
1473 		log_debug ("data: const = %s",
1474 		      print_hex_1 (expr -> data.const_data.len,
1475 				   expr -> data.const_data.data, 60));
1476 #endif
1477 		data_string_copy (result,
1478 				  &expr -> data.const_data, file, line);
1479 		return 1;
1480 
1481 		/* Hostname lookup... */
1482 	      case expr_host_lookup:
1483 		s0 = do_host_lookup (result, expr -> data.host_lookup);
1484 #if defined (DEBUG_EXPRESSIONS)
1485 		log_debug ("data: DNS lookup (%s) = %s",
1486 		      expr -> data.host_lookup -> hostname,
1487 		      (s0
1488 		       ? print_dotted_quads (result -> len, result -> data)
1489 		       : "NULL"));
1490 #endif
1491 		return s0;
1492 
1493 		/* Concatenation... */
1494 	      case expr_concat:
1495 		memset (&data, 0, sizeof data);
1496 		s0 = evaluate_data_expression (&data, packet, lease,
1497 					       client_state,
1498 					       in_options, cfg_options, scope,
1499 					       expr -> data.concat [0], MDL);
1500 		memset (&other, 0, sizeof other);
1501 		s1 = evaluate_data_expression (&other, packet, lease,
1502 					       client_state,
1503 					       in_options, cfg_options, scope,
1504 					       expr -> data.concat [1], MDL);
1505 
1506 		if (s0 && s1) {
1507 		    result -> len = data.len + other.len;
1508 		    if (!buffer_allocate (&result -> buffer,
1509 					  (result -> len + other.terminated),
1510 					  file, line)) {
1511 				log_error ("data: concat: no memory");
1512 				result -> len = 0;
1513 				data_string_forget (&data, MDL);
1514 				data_string_forget (&other, MDL);
1515 				return 0;
1516 			}
1517 			result -> data = &result -> buffer -> data [0];
1518 			memcpy (result -> buffer -> data, data.data, data.len);
1519 			memcpy (&result -> buffer -> data [data.len],
1520 				other.data, other.len + other.terminated);
1521 		}
1522 
1523 		if (s0)
1524 			data_string_forget (&data, MDL);
1525 		if (s1)
1526 			data_string_forget (&other, MDL);
1527 #if defined (DEBUG_EXPRESSIONS)
1528 		log_debug ("data: concat (%s, %s) = %s",
1529 		      s0 ? print_hex_1 (data.len, data.data, 20) : "NULL",
1530 		      s1 ? print_hex_2 (other.len, other.data, 20) : "NULL",
1531 		      ((s0 && s1)
1532 		       ? print_hex_3 (result -> len, result -> data, 30)
1533 		       : "NULL"));
1534 #endif
1535 		return s0 && s1;
1536 
1537 	      case expr_encode_int8:
1538 		s0 = evaluate_numeric_expression (&len, packet, lease,
1539 						  client_state,
1540 						  in_options, cfg_options,
1541 						  scope,
1542 						  expr -> data.encode_int);
1543 		if (s0) {
1544 			result -> len = 1;
1545 			if (!buffer_allocate (&result -> buffer,
1546 					      1, file, line)) {
1547 				log_error ("data: encode_int8: no memory");
1548 				result -> len = 0;
1549 				s0 = 0;
1550 			} else {
1551 				result -> data = &result -> buffer -> data [0];
1552 				result -> buffer -> data [0] = len;
1553 			}
1554 		} else
1555 			result -> len = 0;
1556 
1557 #if defined (DEBUG_EXPRESSIONS)
1558 		if (!s0)
1559 			log_debug ("data: encode_int8 (NULL) = NULL");
1560 		else
1561 			log_debug ("data: encode_int8 (%ld) = %s", len,
1562 				  print_hex_2 (result -> len,
1563 					       result -> data, 20));
1564 #endif
1565 		return s0;
1566 
1567 
1568 	      case expr_encode_int16:
1569 		s0 = evaluate_numeric_expression (&len, packet, lease,
1570 						  client_state,
1571 						  in_options, cfg_options,
1572 						  scope,
1573 						  expr -> data.encode_int);
1574 		if (s0) {
1575 			result -> len = 2;
1576 			if (!buffer_allocate (&result -> buffer, 2,
1577 					      file, line)) {
1578 				log_error ("data: encode_int16: no memory");
1579 				result -> len = 0;
1580 				s0 = 0;
1581 			} else {
1582 				result -> data = &result -> buffer -> data [0];
1583 				putUShort (result -> buffer -> data, len);
1584 			}
1585 		} else
1586 			result -> len = 0;
1587 
1588 #if defined (DEBUG_EXPRESSIONS)
1589 		if (!s0)
1590 			log_debug ("data: encode_int16 (NULL) = NULL");
1591 		else
1592 			log_debug ("data: encode_int16 (%ld) = %s", len,
1593 				  print_hex_2 (result -> len,
1594 					       result -> data, 20));
1595 #endif
1596 		return s0;
1597 
1598 	      case expr_encode_int32:
1599 		s0 = evaluate_numeric_expression (&len, packet, lease,
1600 						  client_state,
1601 						  in_options, cfg_options,
1602 						  scope,
1603 						  expr -> data.encode_int);
1604 		if (s0) {
1605 			result -> len = 4;
1606 			if (!buffer_allocate (&result -> buffer, 4,
1607 					      file, line)) {
1608 				log_error ("data: encode_int32: no memory");
1609 				result -> len = 0;
1610 				s0 = 0;
1611 			} else {
1612 				result -> data = &result -> buffer -> data [0];
1613 				putULong (result -> buffer -> data, len);
1614 			}
1615 		} else
1616 			result -> len = 0;
1617 
1618 #if defined (DEBUG_EXPRESSIONS)
1619 		if (!s0)
1620 			log_debug ("data: encode_int32 (NULL) = NULL");
1621 		else
1622 			log_debug ("data: encode_int32 (%ld) = %s", len,
1623 				  print_hex_2 (result -> len,
1624 					       result -> data, 20));
1625 #endif
1626 		return s0;
1627 
1628 	      case expr_binary_to_ascii:
1629 		/* Evaluate the base (offset) and width (len): */
1630 		s0 = evaluate_numeric_expression
1631 			(&offset, packet, lease, client_state, in_options,
1632 			 cfg_options, scope, expr -> data.b2a.base);
1633 		s1 = evaluate_numeric_expression (&len, packet, lease,
1634 						  client_state,
1635 						  in_options, cfg_options,
1636 						  scope,
1637 						  expr -> data.b2a.width);
1638 
1639 		/* Evaluate the separator string. */
1640 		memset (&data, 0, sizeof data);
1641 		s2 = evaluate_data_expression (&data, packet, lease,
1642 					       client_state,
1643 					       in_options, cfg_options, scope,
1644 					       expr -> data.b2a.separator,
1645 					       MDL);
1646 
1647 		/* Evaluate the data to be converted. */
1648 		memset (&other, 0, sizeof other);
1649 		s3 = evaluate_data_expression (&other, packet, lease,
1650 					       client_state,
1651 					       in_options, cfg_options, scope,
1652 					       expr -> data.b2a.buffer, MDL);
1653 
1654 		if (s0 && s1 && s2 && s3) {
1655 			unsigned buflen, i;
1656 
1657 			if (len != 8 && len != 16 && len != 32) {
1658 				log_info ("binary_to_ascii: %s %ld!",
1659 					  "invalid width", len);
1660 				status = 0;
1661 				goto b2a_out;
1662 			}
1663 			len /= 8;
1664 
1665 			/* The buffer must be a multiple of the number's
1666 			   width. */
1667 			if (other.len % len) {
1668 				log_info ("binary-to-ascii: %s %d %s %ld!",
1669 					  "length of buffer", other.len,
1670 					  "not a multiple of width", len);
1671 				status = 0;
1672 				goto b2a_out;
1673 			}
1674 
1675 			/* Count the width of the output. */
1676 			buflen = 0;
1677 			for (i = 0; i < other.len; i += len) {
1678 				if (len == 1) {
1679 					if (offset == 8) {
1680 						if (other.data [i] < 8)
1681 							buflen++;
1682 						else if (other.data [i] < 64)
1683 							buflen += 2;
1684 						else
1685 							buflen += 3;
1686 					} else if (offset == 10) {
1687 						if (other.data [i] < 10)
1688 							buflen++;
1689 						else if (other.data [i] < 100)
1690 							buflen += 2;
1691 						else
1692 							buflen += 3;
1693 					} else if (offset == 16) {
1694 						if (other.data [i] < 16)
1695 							buflen++;
1696 						else
1697 							buflen += 2;
1698 					} else
1699 						buflen += (converted_length
1700 							   (&other.data [i],
1701 							    offset, 1));
1702 				} else
1703 					buflen += (converted_length
1704 						   (&other.data [i],
1705 						    offset, len));
1706 				if (i + len != other.len)
1707 					buflen += data.len;
1708 			}
1709 
1710 			if (!buffer_allocate (&result -> buffer,
1711 					      buflen + 1, file, line)) {
1712 				log_error ("data: binary-to-ascii: no memory");
1713 				status = 0;
1714 				goto b2a_out;
1715 			}
1716 			result -> data = &result -> buffer -> data [0];
1717 			result -> len = buflen;
1718 			result -> terminated = 1;
1719 
1720 			buflen = 0;
1721 			for (i = 0; i < other.len; i += len) {
1722 				buflen += (binary_to_ascii
1723 					   (&result -> buffer -> data [buflen],
1724 					    &other.data [i], offset, len));
1725 				if (i + len != other.len) {
1726 					memcpy (&result ->
1727 						buffer -> data [buflen],
1728 						data.data, data.len);
1729 					buflen += data.len;
1730 				}
1731 			}
1732 			/* NUL terminate. */
1733 			result -> buffer -> data [buflen] = 0;
1734 			status = 1;
1735 		} else
1736 			status = 0;
1737 
1738 	      b2a_out:
1739 #if defined (DEBUG_EXPRESSIONS)
1740 		log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
1741 		      s0 ? print_dec_1 (offset) : "NULL",
1742 		      s1 ? print_dec_2 (len) : "NULL",
1743 		      s2 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1744 		      s3 ? print_hex_2 (other.len, other.data, 30) : "NULL",
1745 		      (status ? print_hex_3 (result -> len, result -> data, 30)
1746 		          : "NULL"));
1747 #endif
1748 		if (s2)
1749 			data_string_forget (&data, MDL);
1750 		if (s3)
1751 			data_string_forget (&other, MDL);
1752 		if (status)
1753 			return 1;
1754 		return 0;
1755 
1756 	      case expr_reverse:
1757 		/* Evaluate the width (len): */
1758 		s0 = evaluate_numeric_expression
1759 			(&len, packet, lease, client_state, in_options,
1760 			 cfg_options, scope, expr -> data.reverse.width);
1761 
1762 		/* Evaluate the data. */
1763 		memset (&data, 0, sizeof data);
1764 		s1 = evaluate_data_expression (&data, packet, lease,
1765 					       client_state,
1766 					       in_options, cfg_options, scope,
1767 					       expr -> data.reverse.buffer,
1768 					       MDL);
1769 
1770 		if (s0 && s1) {
1771 			int i;
1772 
1773 			/* The buffer must be a multiple of the number's
1774 			   width. */
1775 			if (data.len % len) {
1776 				log_info ("reverse: %s %d %s %ld!",
1777 					  "length of buffer", data.len,
1778 					  "not a multiple of width", len);
1779 				status = 0;
1780 				goto reverse_out;
1781 			}
1782 
1783 			/* XXX reverse in place?   I don't think we can. */
1784 			if (!buffer_allocate (&result -> buffer,
1785 					      data.len, file, line)) {
1786 				log_error ("data: reverse: no memory");
1787 				status = 0;
1788 				goto reverse_out;
1789 			}
1790 			result -> data = &result -> buffer -> data [0];
1791 			result -> len = data.len;
1792 			result -> terminated = 0;
1793 
1794 			for (i = 0; i < data.len; i += len) {
1795 				memcpy (&result -> buffer -> data [i],
1796 					&data.data [data.len - i - len], len);
1797 			}
1798 			status = 1;
1799 		} else
1800 			status = 0;
1801 
1802 	      reverse_out:
1803 #if defined (DEBUG_EXPRESSIONS)
1804 		log_debug ("data: reverse (%s, %s) = %s",
1805 		      s0 ? print_dec_1 (len) : "NULL",
1806 		      s1 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1807 		      (status ? print_hex_3 (result -> len, result -> data, 30)
1808 		          : "NULL"));
1809 #endif
1810 		if (s0)
1811 			data_string_forget (&data, MDL);
1812 		if (status)
1813 			return 1;
1814 		return 0;
1815 
1816 	      case expr_leased_address:
1817 		if (!lease) {
1818 			log_debug("data: \"leased-address\" configuration "
1819 				  "directive: there is no lease associated "
1820 				  "with this client.");
1821 			return 0;
1822 		}
1823 		result -> len = lease -> ip_addr.len;
1824 		if (buffer_allocate (&result -> buffer, result -> len,
1825 				     file, line)) {
1826 			result -> data = &result -> buffer -> data [0];
1827 			memcpy (&result -> buffer -> data [0],
1828 				lease -> ip_addr.iabuf, lease -> ip_addr.len);
1829 			result -> terminated = 0;
1830 		} else {
1831 			log_error ("data: leased-address: no memory.");
1832 			return 0;
1833 		}
1834 #if defined (DEBUG_EXPRESSIONS)
1835 		log_debug ("data: leased-address = %s",
1836 		      print_hex_1 (result -> len, result -> data, 60));
1837 #endif
1838 		return 1;
1839 
1840 	      case expr_pick_first_value:
1841 		memset (&data, 0, sizeof data);
1842 		if ((evaluate_data_expression
1843 		     (result, packet,
1844 		      lease, client_state, in_options, cfg_options,
1845 		      scope, expr -> data.pick_first_value.car, MDL))) {
1846 #if defined (DEBUG_EXPRESSIONS)
1847 			log_debug ("data: pick_first_value (%s, xxx)",
1848 				   print_hex_1 (result -> len,
1849 						result -> data, 40));
1850 #endif
1851 			return 1;
1852 		}
1853 
1854 		if (expr -> data.pick_first_value.cdr &&
1855 		    (evaluate_data_expression
1856 		     (result, packet,
1857 		      lease, client_state, in_options, cfg_options,
1858 		      scope, expr -> data.pick_first_value.cdr, MDL))) {
1859 #if defined (DEBUG_EXPRESSIONS)
1860 			log_debug ("data: pick_first_value (NULL, %s)",
1861 				   print_hex_1 (result -> len,
1862 						result -> data, 40));
1863 #endif
1864 			return 1;
1865 		}
1866 
1867 #if defined (DEBUG_EXPRESSIONS)
1868 		log_debug ("data: pick_first_value (NULL, NULL) = NULL");
1869 #endif
1870 		return 0;
1871 
1872 	      case expr_host_decl_name:
1873 		if (!lease || !lease -> host) {
1874 			log_error ("data: host_decl_name: not available");
1875 			return 0;
1876 		}
1877 		result -> len = strlen (lease -> host -> name);
1878 		if (buffer_allocate (&result -> buffer,
1879 				     result -> len + 1, file, line)) {
1880 			result -> data = &result -> buffer -> data [0];
1881 			strcpy ((char *)&result -> buffer -> data [0],
1882 				lease -> host -> name);
1883 			result -> terminated = 1;
1884 		} else {
1885 			log_error ("data: host-decl-name: no memory.");
1886 			return 0;
1887 		}
1888 #if defined (DEBUG_EXPRESSIONS)
1889 		log_debug ("data: host-decl-name = %s", lease -> host -> name);
1890 #endif
1891 		return 1;
1892 
1893 	      case expr_null:
1894 #if defined (DEBUG_EXPRESSIONS)
1895 		log_debug ("data: null = NULL");
1896 #endif
1897 		return 0;
1898 
1899 	      case expr_variable_reference:
1900 		if (scope && *scope) {
1901 		    binding = find_binding (*scope, expr -> data.variable);
1902 
1903 		    if (binding && binding -> value) {
1904 			if (binding -> value -> type == binding_data) {
1905 			    data_string_copy (result,
1906 					      &binding -> value -> value.data,
1907 					      file, line);
1908 			    s0 = 1;
1909 			} else if (binding -> value -> type != binding_data) {
1910 			    log_error ("binding type %d in %s.",
1911 				       binding -> value -> type,
1912 				       "evaluate_data_expression");
1913 			    s0 = 0;
1914 			} else
1915 			    s0 = 0;
1916 		    } else
1917 			s0 = 0;
1918 		} else
1919 		    s0 = 0;
1920 #if defined (DEBUG_EXPRESSIONS)
1921 		log_debug ("data: %s = %s", expr -> data.variable,
1922 			   s0 ? print_hex_1 (result -> len,
1923 					     result -> data, 50) : "NULL");
1924 #endif
1925 		return s0;
1926 
1927 	      case expr_funcall:
1928 		bv = (struct binding_value *)0;
1929 		s0 = evaluate_expression (&bv, packet, lease, client_state,
1930 					  in_options, cfg_options,
1931 					  scope, expr, MDL);
1932 		if (s0) {
1933 			if (bv -> type != binding_data)
1934 				log_error ("%s() returned type %d in %s.",
1935 					   expr -> data.funcall.name,
1936 					   bv -> type,
1937 					   "evaluate_data_expression");
1938 			else
1939 				data_string_copy (result, &bv -> value.data,
1940 						  file, line);
1941 			binding_value_dereference (&bv, MDL);
1942 		}
1943 #if defined (DEBUG_EXPRESSIONS)
1944 		log_debug ("data: %s = %s", expr -> data.funcall.name,
1945 			   s0 ? print_hex_1 (result -> len,
1946 					     result -> data, 50) : "NULL");
1947 #endif
1948 		break;
1949 
1950 		/* Extract the filename. */
1951 	      case expr_filename:
1952 		if (packet && packet -> raw -> file [0]) {
1953 			char *fn =
1954 				memchr (packet -> raw -> file, 0,
1955 					sizeof packet -> raw -> file);
1956 			if (!fn)
1957 				fn = ((char *)packet -> raw -> file +
1958 				      sizeof packet -> raw -> file);
1959 			result -> len = fn - &(packet -> raw -> file [0]);
1960 			if (buffer_allocate (&result -> buffer,
1961 					     result -> len + 1, file, line)) {
1962 				result -> data = &result -> buffer -> data [0];
1963 				memcpy (&result -> buffer -> data [0],
1964 					packet -> raw -> file,
1965 					result -> len);
1966 				result -> buffer -> data [result -> len] = 0;
1967 				result -> terminated = 1;
1968 				s0 = 1;
1969 			} else {
1970 				log_error ("data: filename: no memory.");
1971 				s0 = 0;
1972 			}
1973 		} else
1974 			s0 = 0;
1975 
1976 #if defined (DEBUG_EXPRESSIONS)
1977 		log_info ("data: filename = \"%s\"",
1978 			  s0 ? (const char *)(result -> data) : "NULL");
1979 #endif
1980 		return s0;
1981 
1982 		/* Extract the server name. */
1983 	      case expr_sname:
1984 		if (packet && packet -> raw -> sname [0]) {
1985 			char *fn =
1986 				memchr (packet -> raw -> sname, 0,
1987 					sizeof packet -> raw -> sname);
1988 			if (!fn)
1989 				fn = ((char *)packet -> raw -> sname +
1990 				      sizeof packet -> raw -> sname);
1991 			result -> len = fn - &packet -> raw -> sname [0];
1992 			if (buffer_allocate (&result -> buffer,
1993 					     result -> len + 1, file, line)) {
1994 				result -> data = &result -> buffer -> data [0];
1995 				memcpy (&result -> buffer -> data [0],
1996 					packet -> raw -> sname,
1997 					result -> len);
1998 				result -> buffer -> data [result -> len] = 0;
1999 				result -> terminated = 1;
2000 				s0 = 1;
2001 			} else {
2002 				log_error ("data: sname: no memory.");
2003 				s0 = 0;
2004 			}
2005 		} else
2006 			s0 = 0;
2007 
2008 #if defined (DEBUG_EXPRESSIONS)
2009 		log_info ("data: sname = \"%s\"",
2010 			  s0 ? (const char *)(result -> data) : "NULL");
2011 #endif
2012 		return s0;
2013 
2014 		/* Provide the system's local hostname as a return value. */
2015 	      case expr_gethostname:
2016 		/*
2017 		 * Allocate a buffer to return.
2018 		 *
2019 		 * The largest valid hostname is maybe 64 octets at a single
2020 		 * label, or 255 octets if you think a hostname is allowed
2021 		 * to contain labels (plus termination).
2022 		 */
2023 		memset(result, 0, sizeof(*result));
2024 		if (!buffer_allocate(&result->buffer, 255, file, line)) {
2025 			log_error("data: gethostname(): no memory for buffer");
2026 			return 0;
2027 		}
2028 		result->data = result->buffer->data;
2029 
2030 		/*
2031 		 * On successful completion, gethostname() resturns 0.  It may
2032 		 * not null-terminate the string if there was insufficient
2033 		 * space.
2034 		 */
2035 		if (!gethostname((char *)result->buffer->data, 255)) {
2036 			if (result->buffer->data[255] == '\0')
2037 				result->len =
2038 					strlen((char *)result->buffer->data);
2039 			else
2040 				result->len = 255;
2041 			return 1;
2042 		}
2043 
2044 		data_string_forget(result, MDL);
2045 		return 0;
2046 
2047 		/* Find an option within a v6relay context
2048 		 *
2049 		 * The numeric expression in relay indicates which relay
2050 		 * to try and use as the context.  The relays are numbered
2051 		 * 1 to 32 with 1 being the one closest to the client and
2052 		 * 32 closest to the server.  A value of greater than 33
2053 		 * indicates using the one closest to the server whatever
2054 		 * the count.  A value of 0 indicates not using the relay
2055 		 * options, this is included for completeness and consistency
2056 		 * with the host-identier code.
2057 		 *
2058 		 * The data expression in roption is evaluated in that
2059 		 * context and the result returned.
2060 		 */
2061 	      case expr_v6relay:
2062 		len = 0;
2063 		s1 = 0;
2064 		memset (&data, 0, sizeof data);
2065 
2066 		/* Evaluate the relay count */
2067 		s0 = evaluate_numeric_expression(&len, packet, lease,
2068 						 client_state,
2069 						 in_options, cfg_options,
2070 						 scope,
2071 						 expr->data.v6relay.relay);
2072 
2073 		/* no number or an obviously invalid number */
2074 		if ((s0 == 0) ||
2075 		    ((len > 0) &&
2076 		     ((packet == NULL) ||
2077 		      (packet->dhcpv6_container_packet == NULL)))) {
2078 #if defined (DEBUG_EXPRESSIONS)
2079 			log_debug("data: v6relay(%d) = NULL", len);
2080 #endif
2081 			return (0);
2082 		}
2083 
2084 		/* Find the correct packet for the requested relay */
2085 		i = len;
2086 		relay_packet = packet;
2087 		relay_options = in_options;
2088 		while ((i != 0) &&
2089 		       (relay_packet->dhcpv6_container_packet != NULL)) {
2090 			relay_packet = relay_packet->dhcpv6_container_packet;
2091 			relay_options = relay_packet->options;
2092 			i--;
2093 		}
2094 		/* We wanted a specific relay but were unable to find it */
2095 		if ((len <= MAX_V6RELAY_HOPS) && (i != 0)) {
2096 #if defined (DEBUG_EXPRESSIONS)
2097 			log_debug("data: v6relay(%d) = NULL", len);
2098 #endif
2099 			return (0);
2100 		}
2101 
2102 		s1 = evaluate_data_expression(&data, relay_packet, lease,
2103 					      client_state, relay_options,
2104 					      cfg_options, scope,
2105 					      expr->data.v6relay.roption,
2106 					      MDL);
2107 
2108 		if (s1) {
2109 			data_string_copy(result, &data, file, line);
2110 			data_string_forget(&data, MDL);
2111 		}
2112 
2113 #if defined (DEBUG_EXPRESSIONS)
2114 		log_debug("data: v6relay(%d) = %s", len,
2115 			  s1 ? print_hex_3(result->len, result->data, 30)
2116 			  : "NULL");
2117 #endif
2118 		return (s1);
2119 
2120 	      case expr_check:
2121 	      case expr_equal:
2122 	      case expr_not_equal:
2123 	      case expr_regex_match:
2124 	      case expr_iregex_match:
2125 	      case expr_and:
2126 	      case expr_or:
2127 	      case expr_not:
2128 	      case expr_match:
2129 	      case expr_static:
2130 	      case expr_known:
2131 	      case expr_none:
2132 	      case expr_exists:
2133 	      case expr_variable_exists:
2134 		log_error ("Boolean opcode in evaluate_data_expression: %d",
2135 		      expr -> op);
2136 		return 0;
2137 
2138 	      case expr_extract_int8:
2139 	      case expr_extract_int16:
2140 	      case expr_extract_int32:
2141 	      case expr_const_int:
2142 	      case expr_lease_time:
2143 	      case expr_dns_transaction:
2144 	      case expr_add:
2145 	      case expr_subtract:
2146 	      case expr_multiply:
2147 	      case expr_divide:
2148 	      case expr_remainder:
2149 	      case expr_binary_and:
2150 	      case expr_binary_or:
2151 	      case expr_binary_xor:
2152 	      case expr_client_state:
2153 		log_error ("Numeric opcode in evaluate_data_expression: %d",
2154 		      expr -> op);
2155 		return 0;
2156 
2157 	      case expr_ns_add:
2158 	      case expr_ns_delete:
2159 	      case expr_ns_exists:
2160 	      case expr_ns_not_exists:
2161 		log_error ("dns opcode in evaluate_boolean_expression: %d",
2162 		      expr -> op);
2163 		return 0;
2164 
2165 	      case expr_function:
2166 		log_error ("function definition in evaluate_data_expression");
2167 		return 0;
2168 
2169 	      case expr_arg:
2170 		break;
2171 	}
2172 
2173 	log_error ("Bogus opcode in evaluate_data_expression: %d", expr -> op);
2174 	return 0;
2175 }
2176 
2177 int evaluate_numeric_expression (result, packet, lease, client_state,
2178 				 in_options, cfg_options, scope, expr)
2179 	unsigned long *result;
2180 	struct packet *packet;
2181 	struct lease *lease;
2182 	struct client_state *client_state;
2183 	struct option_state *in_options;
2184 	struct option_state *cfg_options;
2185 	struct binding_scope **scope;
2186 	struct expression *expr;
2187 {
2188 	struct data_string data;
2189 	int status, sleft, sright;
2190 
2191 	struct binding *binding;
2192 	struct binding_value *bv;
2193 	unsigned long ileft, iright;
2194 	int rc = 0;
2195 
2196 	switch (expr -> op) {
2197 	      case expr_check:
2198 	      case expr_equal:
2199 	      case expr_not_equal:
2200 	      case expr_regex_match:
2201 	      case expr_iregex_match:
2202 	      case expr_and:
2203 	      case expr_or:
2204 	      case expr_not:
2205 	      case expr_match:
2206 	      case expr_static:
2207 	      case expr_known:
2208 	      case expr_none:
2209 	      case expr_exists:
2210 	      case expr_variable_exists:
2211 		log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2212 		      expr -> op);
2213 		return 0;
2214 
2215 	      case expr_substring:
2216 	      case expr_suffix:
2217 	      case expr_lcase:
2218 	      case expr_ucase:
2219 	      case expr_option:
2220 	      case expr_hardware:
2221 	      case expr_const_data:
2222 	      case expr_packet:
2223 	      case expr_concat:
2224 	      case expr_encapsulate:
2225 	      case expr_host_lookup:
2226 	      case expr_encode_int8:
2227 	      case expr_encode_int16:
2228 	      case expr_encode_int32:
2229 	      case expr_binary_to_ascii:
2230 	      case expr_reverse:
2231 	      case expr_filename:
2232 	      case expr_sname:
2233 	      case expr_pick_first_value:
2234 	      case expr_host_decl_name:
2235 	      case expr_config_option:
2236 	      case expr_leased_address:
2237 	      case expr_null:
2238 	      case expr_gethostname:
2239 	      case expr_v6relay:
2240 		log_error ("Data opcode in evaluate_numeric_expression: %d",
2241 		      expr -> op);
2242 		return 0;
2243 
2244 	      case expr_extract_int8:
2245 		memset (&data, 0, sizeof data);
2246 		status = evaluate_data_expression
2247 			(&data, packet, lease, client_state, in_options,
2248 			 cfg_options, scope, expr -> data.extract_int, MDL);
2249 		if (status)
2250 			*result = data.data [0];
2251 #if defined (DEBUG_EXPRESSIONS)
2252 		log_debug ("num: extract_int8 (%s) = %s",
2253 		      status ? print_hex_1 (data.len, data.data, 60) : "NULL",
2254 		      status ? print_dec_1 (*result) : "NULL" );
2255 #endif
2256 		if (status) data_string_forget (&data, MDL);
2257 		return status;
2258 
2259 	      case expr_extract_int16:
2260 		memset(&data, 0, sizeof(data));
2261 		status = (evaluate_data_expression
2262 			  (&data, packet, lease, client_state, in_options,
2263 			   cfg_options, scope, expr->data.extract_int, MDL));
2264 		if (status && data.len >= 2) {
2265 			*result = getUShort(data.data);
2266 			rc = 1;
2267 		}
2268 #if defined (DEBUG_EXPRESSIONS)
2269 		if (rc == 1) {
2270 			log_debug("num: extract_int16 (%s) = %ld",
2271 				  print_hex_1(data.len, data.data, 60),
2272 				  *result);
2273 		} else {
2274 			log_debug("num: extract_int16 (NULL) = NULL");
2275 		}
2276 #endif
2277 		if (status)
2278 			data_string_forget(&data, MDL);
2279 
2280 		return (rc);
2281 
2282 	      case expr_extract_int32:
2283 		memset (&data, 0, sizeof data);
2284 		status = (evaluate_data_expression
2285 			  (&data, packet, lease, client_state, in_options,
2286 			   cfg_options, scope, expr -> data.extract_int, MDL));
2287 		if (status && data.len >= 4) {
2288 			*result = getULong (data.data);
2289 			rc = 1;
2290 		}
2291 #if defined (DEBUG_EXPRESSIONS)
2292 		if (rc == 1) {
2293 			log_debug ("num: extract_int32 (%s) = %ld",
2294 				   print_hex_1 (data.len, data.data, 60),
2295 				   *result);
2296 		} else {
2297 			log_debug ("num: extract_int32 (NULL) = NULL");
2298 		}
2299 #endif
2300 		if (status) data_string_forget (&data, MDL);
2301 		return (rc);
2302 
2303 	      case expr_const_int:
2304 		*result = expr -> data.const_int;
2305 #if defined (DEBUG_EXPRESSIONS)
2306 		log_debug ("number: CONSTANT = %ld", *result);
2307 #endif
2308 		return 1;
2309 
2310 	      case expr_lease_time:
2311 		if (!lease) {
2312 			log_error("data: leased_lease: not available");
2313 			return (0);
2314 		}
2315 		if (lease->ends < cur_time) {
2316 			log_error("%s %lu when it is now %lu",
2317 				  "data: lease_time: lease ends at",
2318 				  (long)(lease->ends), (long)cur_time);
2319 			return (0);
2320 		}
2321 		*result = lease->ends - cur_time;
2322 #if defined (DEBUG_EXPRESSIONS)
2323 		log_debug("number: lease-time = (%lu - %lu) = %ld",
2324 			  (long unsigned)lease->ends,
2325 			  (long unsigned)cur_time, *result);
2326 #endif
2327 		return (1);
2328 
2329 	      case expr_variable_reference:
2330 		if (scope && *scope) {
2331 		    binding = find_binding (*scope, expr -> data.variable);
2332 
2333 		    if (binding && binding -> value) {
2334 			if (binding -> value -> type == binding_numeric) {
2335 				*result = binding -> value -> value.intval;
2336 			    status = 1;
2337 			} else {
2338 				log_error ("binding type %d in %s.",
2339 					   binding -> value -> type,
2340 					   "evaluate_numeric_expression");
2341 				status = 0;
2342 			}
2343 		    } else
2344 			status = 0;
2345 		} else
2346 		    status = 0;
2347 #if defined (DEBUG_EXPRESSIONS)
2348 		if (status)
2349 			log_debug ("numeric: %s = %ld",
2350 				   expr -> data.variable, *result);
2351 		else
2352 			log_debug ("numeric: %s = NULL",
2353 				   expr -> data.variable);
2354 #endif
2355 		return status;
2356 
2357 	      case expr_funcall:
2358 		bv = (struct binding_value *)0;
2359 		status = evaluate_expression (&bv, packet, lease,
2360 					      client_state,
2361 					      in_options, cfg_options,
2362 					      scope, expr, MDL);
2363 		if (status) {
2364 			if (bv -> type != binding_numeric)
2365 				log_error ("%s() returned type %d in %s.",
2366 					   expr -> data.funcall.name,
2367 					   bv -> type,
2368 					   "evaluate_numeric_expression");
2369 			else
2370 				*result = bv -> value.intval;
2371 			binding_value_dereference (&bv, MDL);
2372 		}
2373 #if defined (DEBUG_EXPRESSIONS)
2374 		log_debug ("data: %s = %ld", expr -> data.funcall.name,
2375 			   status ? *result : 0);
2376 #endif
2377 		break;
2378 
2379 	      case expr_add:
2380 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2381 						     client_state,
2382 						     in_options, cfg_options,
2383 						     scope,
2384 						     expr -> data.and [0]);
2385 		sright = evaluate_numeric_expression (&iright, packet, lease,
2386 						      client_state,
2387 						      in_options, cfg_options,
2388 						      scope,
2389 						      expr -> data.and [1]);
2390 
2391 #if defined (DEBUG_EXPRESSIONS)
2392 		if (sleft && sright)
2393 			log_debug ("num: %ld + %ld = %ld",
2394 				   ileft, iright, ileft + iright);
2395 		else if (sleft)
2396 			log_debug ("num: %ld + NULL = NULL", ileft);
2397 		else
2398 			log_debug ("num: NULL + %ld = NULL", iright);
2399 #endif
2400 		if (sleft && sright) {
2401 			*result = ileft + iright;
2402 			return 1;
2403 		}
2404 		return 0;
2405 
2406 	      case expr_subtract:
2407 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2408 						     client_state,
2409 						     in_options, cfg_options,
2410 						     scope,
2411 						     expr -> data.and [0]);
2412 		sright = evaluate_numeric_expression (&iright, packet, lease,
2413 						      client_state,
2414 						      in_options, cfg_options,
2415 						      scope,
2416 						      expr -> data.and [1]);
2417 
2418 #if defined (DEBUG_EXPRESSIONS)
2419 		if (sleft && sright)
2420 			log_debug ("num: %ld - %ld = %ld",
2421 				   ileft, iright, ileft - iright);
2422 		else if (sleft)
2423 			log_debug ("num: %ld - NULL = NULL", ileft);
2424 		else
2425 			log_debug ("num: NULL - %ld = NULL", iright);
2426 #endif
2427 		if (sleft && sright) {
2428 			*result = ileft - iright;
2429 			return 1;
2430 		}
2431 		return 0;
2432 
2433 	      case expr_multiply:
2434 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2435 						     client_state,
2436 						     in_options, cfg_options,
2437 						     scope,
2438 						     expr -> data.and [0]);
2439 		sright = evaluate_numeric_expression (&iright, packet, lease,
2440 						      client_state,
2441 						      in_options, cfg_options,
2442 						      scope,
2443 						      expr -> data.and [1]);
2444 
2445 #if defined (DEBUG_EXPRESSIONS)
2446 		if (sleft && sright)
2447 			log_debug ("num: %ld * %ld = %ld",
2448 				   ileft, iright, ileft * iright);
2449 		else if (sleft)
2450 			log_debug ("num: %ld * NULL = NULL", ileft);
2451 		else
2452 			log_debug ("num: NULL * %ld = NULL", iright);
2453 #endif
2454 		if (sleft && sright) {
2455 			*result = ileft * iright;
2456 			return 1;
2457 		}
2458 		return 0;
2459 
2460 	      case expr_divide:
2461 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2462 						     client_state,
2463 						     in_options, cfg_options,
2464 						     scope,
2465 						     expr -> data.and [0]);
2466 		sright = evaluate_numeric_expression (&iright, packet, lease,
2467 						      client_state,
2468 						      in_options, cfg_options,
2469 						      scope,
2470 						      expr -> data.and [1]);
2471 
2472 #if defined (DEBUG_EXPRESSIONS)
2473 		if (sleft && sright) {
2474 			if (iright != 0)
2475 				log_debug ("num: %ld / %ld = %ld",
2476 					   ileft, iright, ileft / iright);
2477 			else
2478 				log_debug ("num: %ld / %ld = NULL",
2479 					   ileft, iright);
2480 		} else if (sleft)
2481 			log_debug ("num: %ld / NULL = NULL", ileft);
2482 		else
2483 			log_debug ("num: NULL / %ld = NULL", iright);
2484 #endif
2485 		if (sleft && sright && iright) {
2486 			*result = ileft / iright;
2487 			return 1;
2488 		}
2489 		return 0;
2490 
2491 	      case expr_remainder:
2492 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2493 						     client_state,
2494 						     in_options, cfg_options,
2495 						     scope,
2496 						     expr -> data.and [0]);
2497 		sright = evaluate_numeric_expression (&iright, packet, lease,
2498 						      client_state,
2499 						      in_options, cfg_options,
2500 						      scope,
2501 						      expr -> data.and [1]);
2502 
2503 #if defined (DEBUG_EXPRESSIONS)
2504 		if (sleft && sright) {
2505 			if (iright != 0)
2506 				log_debug ("num: %ld %% %ld = %ld",
2507 					   ileft, iright, ileft % iright);
2508 			else
2509 				log_debug ("num: %ld %% %ld = NULL",
2510 					   ileft, iright);
2511 		} else if (sleft)
2512 			log_debug ("num: %ld %% NULL = NULL", ileft);
2513 		else
2514 			log_debug ("num: NULL %% %ld = NULL", iright);
2515 #endif
2516 		if (sleft && sright && iright) {
2517 			*result = ileft % iright;
2518 			return 1;
2519 		}
2520 		return 0;
2521 
2522 	      case expr_binary_and:
2523 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2524 						     client_state,
2525 						     in_options, cfg_options,
2526 						     scope,
2527 						     expr -> data.and [0]);
2528 		sright = evaluate_numeric_expression (&iright, packet, lease,
2529 						      client_state,
2530 						      in_options, cfg_options,
2531 						      scope,
2532 						      expr -> data.and [1]);
2533 
2534 #if defined (DEBUG_EXPRESSIONS)
2535 		if (sleft && sright)
2536 			log_debug ("num: %ld | %ld = %ld",
2537 				   ileft, iright, ileft & iright);
2538 		else if (sleft)
2539 			log_debug ("num: %ld & NULL = NULL", ileft);
2540 		else
2541 			log_debug ("num: NULL & %ld = NULL", iright);
2542 #endif
2543 		if (sleft && sright) {
2544 			*result = ileft & iright;
2545 			return 1;
2546 		}
2547 		return 0;
2548 
2549 	      case expr_binary_or:
2550 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2551 						     client_state,
2552 						     in_options, cfg_options,
2553 						     scope,
2554 						     expr -> data.and [0]);
2555 		sright = evaluate_numeric_expression (&iright, packet, lease,
2556 						      client_state,
2557 						      in_options, cfg_options,
2558 						      scope,
2559 						      expr -> data.and [1]);
2560 
2561 #if defined (DEBUG_EXPRESSIONS)
2562 		if (sleft && sright)
2563 			log_debug ("num: %ld | %ld = %ld",
2564 				   ileft, iright, ileft | iright);
2565 		else if (sleft)
2566 			log_debug ("num: %ld | NULL = NULL", ileft);
2567 		else
2568 			log_debug ("num: NULL | %ld = NULL", iright);
2569 #endif
2570 		if (sleft && sright) {
2571 			*result = ileft | iright;
2572 			return 1;
2573 		}
2574 		return 0;
2575 
2576 	      case expr_binary_xor:
2577 		sleft = evaluate_numeric_expression (&ileft, packet, lease,
2578 						     client_state,
2579 						     in_options, cfg_options,
2580 						     scope,
2581 						     expr -> data.and [0]);
2582 		sright = evaluate_numeric_expression (&iright, packet, lease,
2583 						      client_state,
2584 						      in_options, cfg_options,
2585 						      scope,
2586 						      expr -> data.and [1]);
2587 
2588 #if defined (DEBUG_EXPRESSIONS)
2589 		if (sleft && sright)
2590 			log_debug ("num: %ld ^ %ld = %ld",
2591 				   ileft, iright, ileft ^ iright);
2592 		else if (sleft)
2593 			log_debug ("num: %ld ^ NULL = NULL", ileft);
2594 		else
2595 			log_debug ("num: NULL ^ %ld = NULL", iright);
2596 #endif
2597 		if (sleft && sright) {
2598 			*result = ileft ^ iright;
2599 			return 1;
2600 		}
2601 		return 0;
2602 
2603 	      case expr_client_state:
2604 		if (client_state) {
2605 #if defined (DEBUG_EXPRESSIONS)
2606 			log_debug ("num: client-state = %d",
2607 				   client_state -> state);
2608 #endif
2609 			*result = client_state -> state;
2610 			return 1;
2611 		} else {
2612 #if defined (DEBUG_EXPRESSIONS)
2613 			log_debug ("num: client-state = NULL");
2614 #endif
2615 			return 0;
2616 		}
2617 
2618 	      case expr_function:
2619 		log_error ("function definition in evaluate_numeric_expr");
2620 		return 0;
2621 
2622 	      case expr_arg:
2623 		break;
2624 
2625 	      default:
2626 		log_fatal("Impossible case at %s:%d.  Undefined operator "
2627 			  "%d.", MDL, expr->op);
2628 		break;
2629 	}
2630 
2631 	log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op);
2632 	return 0;
2633 }
2634 
2635 /*
2636  * Return data hanging off of an option cache structure, or if there
2637  * isn't any, evaluate the expression hanging off of it and return the
2638  * result of that evaluation.   There should never be both an expression
2639  * and a valid data_string.
2640  *
2641  * returns 0 if there wasn't an expression or it couldn't be evaluated
2642  * returns non-zero if there was an expression or string that was evaluated
2643  * When it returns zero the arguements, in particualr resutl,  should not
2644  * be modified
2645  */
2646 
2647 int evaluate_option_cache (result, packet, lease, client_state,
2648 			   in_options, cfg_options, scope, oc, file, line)
2649 	struct data_string *result;
2650 	struct packet *packet;
2651 	struct lease *lease;
2652 	struct client_state *client_state;
2653 	struct option_state *in_options;
2654 	struct option_state *cfg_options;
2655 	struct binding_scope **scope;
2656 	struct option_cache *oc;
2657 	const char *file;
2658 	int line;
2659 {
2660 	if (oc->data.data != NULL) {
2661 		data_string_copy (result, &oc -> data, file, line);
2662 		return 1;
2663 	}
2664 	if (!oc -> expression)
2665 		return 0;
2666 	return evaluate_data_expression (result, packet, lease, client_state,
2667 					 in_options, cfg_options, scope,
2668 					 oc -> expression, file, line);
2669 }
2670 
2671 /* Evaluate an option cache and extract a boolean from the result,
2672    returning the boolean.   Return false if there is no data. */
2673 
2674 int evaluate_boolean_option_cache (ignorep, packet,
2675 				   lease, client_state, in_options,
2676 				   cfg_options, scope, oc, file, line)
2677 	int *ignorep;
2678 	struct packet *packet;
2679 	struct lease *lease;
2680 	struct client_state *client_state;
2681 	struct option_state *in_options;
2682 	struct option_state *cfg_options;
2683 	struct binding_scope **scope;
2684 	struct option_cache *oc;
2685 	const char *file;
2686 	int line;
2687 {
2688 	struct data_string ds;
2689 	int result;
2690 
2691 	/* So that we can be called with option_lookup as an argument. */
2692 	if (!oc || !in_options)
2693 		return 0;
2694 
2695 	memset (&ds, 0, sizeof ds);
2696 	if (!evaluate_option_cache (&ds, packet,
2697 				    lease, client_state, in_options,
2698 				    cfg_options, scope, oc, file, line))
2699 		return 0;
2700 
2701 	/* The boolean option cache is actually a trinary value.  Zero is
2702 	 * off, one is on, and 2 is 'ignore'.
2703 	 */
2704 	if (ds.len) {
2705 		result = ds.data [0];
2706 		if (result == 2) {
2707 			result = 0;
2708 			if (ignorep != NULL)
2709 				*ignorep = 1;
2710 		} else if (ignorep != NULL)
2711 			*ignorep = 0;
2712 	} else
2713 		result = 0;
2714 	data_string_forget (&ds, MDL);
2715 	return result;
2716 }
2717 
2718 
2719 /* Evaluate a boolean expression and return the result of the evaluation,
2720    or FALSE if it failed. */
2721 
2722 int evaluate_boolean_expression_result (ignorep, packet, lease, client_state,
2723 					in_options, cfg_options, scope, expr)
2724 	int *ignorep;
2725 	struct packet *packet;
2726 	struct lease *lease;
2727 	struct client_state *client_state;
2728 	struct option_state *in_options;
2729 	struct option_state *cfg_options;
2730 	struct binding_scope **scope;
2731 	struct expression *expr;
2732 {
2733 	int result;
2734 
2735 	/* So that we can be called with option_lookup as an argument. */
2736 	if (!expr)
2737 		return 0;
2738 
2739 	if (!evaluate_boolean_expression (&result, packet, lease, client_state,
2740 					  in_options, cfg_options,
2741 					  scope, expr))
2742 		return 0;
2743 
2744 	if (result == 2) {
2745 		*ignorep = 1;
2746 		result = 0;
2747 	} else
2748 		*ignorep = 0;
2749 	return result;
2750 }
2751 
2752 
2753 /* Dereference an expression node, and if the reference count goes to zero,
2754    dereference any data it refers to, and then free it. */
2755 void expression_dereference (eptr, file, line)
2756 	struct expression **eptr;
2757 	const char *file;
2758 	int line;
2759 {
2760 	struct expression *expr = *eptr;
2761 
2762 	/* Zero the pointer. */
2763 	*eptr = (struct expression *)0;
2764 
2765 	/* Decrement the reference count.   If it's nonzero, we're
2766 	   done. */
2767 	--(expr -> refcnt);
2768 	rc_register (file, line, eptr, expr, expr -> refcnt, 1, RC_MISC);
2769 	if (expr -> refcnt > 0)
2770 		return;
2771 	if (expr -> refcnt < 0) {
2772 		log_error ("%s(%d): negative refcnt!", file, line);
2773 #if defined (DEBUG_RC_HISTORY)
2774 		dump_rc_history (expr);
2775 #endif
2776 #if defined (POINTER_DEBUG)
2777 		abort ();
2778 #else
2779 		return;
2780 #endif
2781 	}
2782 
2783 	/* Dereference subexpressions. */
2784 	switch (expr -> op) {
2785 		/* All the binary operators can be handled the same way. */
2786 	      case expr_equal:
2787 	      case expr_not_equal:
2788 	      case expr_regex_match:
2789 	      case expr_iregex_match:
2790 	      case expr_concat:
2791 	      case expr_and:
2792 	      case expr_or:
2793 	      case expr_add:
2794 	      case expr_subtract:
2795 	      case expr_multiply:
2796 	      case expr_divide:
2797 	      case expr_remainder:
2798 	      case expr_binary_and:
2799 	      case expr_binary_or:
2800 	      case expr_binary_xor:
2801 	      case expr_client_state:
2802 		if (expr -> data.equal [0])
2803 			expression_dereference (&expr -> data.equal [0],
2804 						file, line);
2805 		if (expr -> data.equal [1])
2806 			expression_dereference (&expr -> data.equal [1],
2807 						file, line);
2808 		break;
2809 
2810 	      case expr_substring:
2811 		if (expr -> data.substring.expr)
2812 			expression_dereference (&expr -> data.substring.expr,
2813 						file, line);
2814 		if (expr -> data.substring.offset)
2815 			expression_dereference (&expr -> data.substring.offset,
2816 						file, line);
2817 		if (expr -> data.substring.len)
2818 			expression_dereference (&expr -> data.substring.len,
2819 						file, line);
2820 		break;
2821 
2822 	      case expr_suffix:
2823 		if (expr -> data.suffix.expr)
2824 			expression_dereference (&expr -> data.suffix.expr,
2825 						file, line);
2826 		if (expr -> data.suffix.len)
2827 			expression_dereference (&expr -> data.suffix.len,
2828 						file, line);
2829 		break;
2830 
2831 	      case expr_lcase:
2832 		if (expr->data.lcase)
2833 			expression_dereference(&expr->data.lcase, MDL);
2834 		break;
2835 
2836 	      case expr_ucase:
2837 		if (expr->data.ucase)
2838 			expression_dereference(&expr->data.ucase, MDL);
2839 		break;
2840 
2841 	      case expr_not:
2842 		if (expr -> data.not)
2843 			expression_dereference (&expr -> data.not, file, line);
2844 		break;
2845 
2846 	      case expr_packet:
2847 		if (expr -> data.packet.offset)
2848 			expression_dereference (&expr -> data.packet.offset,
2849 						file, line);
2850 		if (expr -> data.packet.len)
2851 			expression_dereference (&expr -> data.packet.len,
2852 						file, line);
2853 		break;
2854 
2855 	      case expr_extract_int8:
2856 	      case expr_extract_int16:
2857 	      case expr_extract_int32:
2858 		if (expr -> data.extract_int)
2859 			expression_dereference (&expr -> data.extract_int,
2860 						file, line);
2861 		break;
2862 
2863 	      case expr_encode_int8:
2864 	      case expr_encode_int16:
2865 	      case expr_encode_int32:
2866 		if (expr -> data.encode_int)
2867 			expression_dereference (&expr -> data.encode_int,
2868 						file, line);
2869 		break;
2870 
2871 	      case expr_encapsulate:
2872 	      case expr_const_data:
2873 		data_string_forget (&expr -> data.const_data, file, line);
2874 		break;
2875 
2876 	      case expr_host_lookup:
2877 		if (expr -> data.host_lookup)
2878 			dns_host_entry_dereference (&expr -> data.host_lookup,
2879 						    file, line);
2880 		break;
2881 
2882 	      case expr_binary_to_ascii:
2883 		if (expr -> data.b2a.base)
2884 			expression_dereference (&expr -> data.b2a.base,
2885 						file, line);
2886 		if (expr -> data.b2a.width)
2887 			expression_dereference (&expr -> data.b2a.width,
2888 						file, line);
2889 		if (expr -> data.b2a.separator)
2890 			expression_dereference (&expr -> data.b2a.separator,
2891 						file, line);
2892 		if (expr -> data.b2a.buffer)
2893 			expression_dereference (&expr -> data.b2a.buffer,
2894 						file, line);
2895 		break;
2896 
2897 	      case expr_pick_first_value:
2898 		if (expr -> data.pick_first_value.car)
2899 		    expression_dereference (&expr -> data.pick_first_value.car,
2900 					    file, line);
2901 		if (expr -> data.pick_first_value.cdr)
2902 		    expression_dereference (&expr -> data.pick_first_value.cdr,
2903 					    file, line);
2904 		break;
2905 
2906 	      case expr_reverse:
2907 		if (expr -> data.reverse.width)
2908 			expression_dereference (&expr -> data.reverse.width,
2909 						file, line);
2910 		if (expr -> data.reverse.buffer)
2911 			expression_dereference
2912 				(&expr -> data.reverse.buffer, file, line);
2913 		break;
2914 
2915 	      case expr_variable_reference:
2916 	      case expr_variable_exists:
2917 		if (expr -> data.variable)
2918 			dfree (expr -> data.variable, file, line);
2919 		break;
2920 
2921 	      case expr_funcall:
2922 		if (expr -> data.funcall.name)
2923 			dfree (expr -> data.funcall.name, file, line);
2924 		if (expr -> data.funcall.arglist)
2925 			expression_dereference (&expr -> data.funcall.arglist,
2926 						file, line);
2927 		break;
2928 
2929 	      case expr_arg:
2930 		if (expr -> data.arg.val)
2931 			expression_dereference (&expr -> data.arg.val,
2932 						file, line);
2933 		if (expr -> data.arg.next)
2934 			expression_dereference (&expr -> data.arg.next,
2935 						file, line);
2936 		break;
2937 
2938 	      case expr_function:
2939 		fundef_dereference (&expr -> data.func, file, line);
2940 		break;
2941 
2942 	      case expr_v6relay:
2943 		if (expr->data.v6relay.relay)
2944 			expression_dereference(&expr->data.v6relay.relay,
2945 					       file, line);
2946 
2947 		if (expr->data.v6relay.roption)
2948 			expression_dereference(&expr->data.v6relay.roption,
2949 					       file, line);
2950 		break;
2951 
2952 		/* No subexpressions. */
2953 	      case expr_leased_address:
2954 	      case expr_lease_time:
2955 	      case expr_filename:
2956 	      case expr_sname:
2957 	      case expr_const_int:
2958 	      case expr_check:
2959 	      case expr_option:
2960 	      case expr_hardware:
2961 	      case expr_exists:
2962 	      case expr_known:
2963 	      case expr_null:
2964 	      case expr_gethostname:
2965 		break;
2966 
2967 	      default:
2968 		break;
2969 	}
2970 	free_expression (expr, MDL);
2971 }
2972 
2973 int is_boolean_expression (expr)
2974 	struct expression *expr;
2975 {
2976 	return (expr -> op == expr_check ||
2977 		expr -> op == expr_exists ||
2978 		expr -> op == expr_variable_exists ||
2979 		expr -> op == expr_equal ||
2980 		expr -> op == expr_not_equal ||
2981 		expr->op == expr_regex_match ||
2982 		expr->op == expr_iregex_match ||
2983 		expr -> op == expr_and ||
2984 		expr -> op == expr_or ||
2985 		expr -> op == expr_not ||
2986 		expr -> op == expr_known ||
2987 		expr -> op == expr_static);
2988 }
2989 
2990 int is_data_expression (expr)
2991 	struct expression *expr;
2992 {
2993 	return (expr->op == expr_substring ||
2994 		expr->op == expr_suffix ||
2995 		expr->op == expr_lcase ||
2996 		expr->op == expr_ucase ||
2997 		expr->op == expr_option ||
2998 		expr->op == expr_hardware ||
2999 		expr->op == expr_const_data ||
3000 		expr->op == expr_packet ||
3001 		expr->op == expr_concat ||
3002 		expr->op == expr_encapsulate ||
3003 		expr->op == expr_encode_int8 ||
3004 		expr->op == expr_encode_int16 ||
3005 		expr->op == expr_encode_int32 ||
3006 		expr->op == expr_host_lookup ||
3007 		expr->op == expr_binary_to_ascii ||
3008 		expr->op == expr_filename ||
3009 		expr->op == expr_sname ||
3010 		expr->op == expr_reverse ||
3011 		expr->op == expr_pick_first_value ||
3012 		expr->op == expr_host_decl_name ||
3013 		expr->op == expr_leased_address ||
3014 		expr->op == expr_config_option ||
3015 		expr->op == expr_null ||
3016 		expr->op == expr_gethostname ||
3017 	        expr->op == expr_v6relay);
3018 }
3019 
3020 int is_numeric_expression (expr)
3021 	struct expression *expr;
3022 {
3023 	return (expr -> op == expr_extract_int8 ||
3024 		expr -> op == expr_extract_int16 ||
3025 		expr -> op == expr_extract_int32 ||
3026 		expr -> op == expr_const_int ||
3027 		expr -> op == expr_lease_time ||
3028 		expr -> op == expr_add ||
3029 		expr -> op == expr_subtract ||
3030 		expr -> op == expr_multiply ||
3031 		expr -> op == expr_divide ||
3032 		expr -> op == expr_remainder ||
3033 		expr -> op == expr_binary_and ||
3034 		expr -> op == expr_binary_or ||
3035 		expr -> op == expr_binary_xor ||
3036 		expr -> op == expr_client_state);
3037 }
3038 
3039 int is_compound_expression (expr)
3040 	struct expression *expr;
3041 {
3042 	return (expr -> op == expr_substring ||
3043 		expr -> op == expr_suffix ||
3044 		expr -> op == expr_option ||
3045 		expr -> op == expr_concat ||
3046 		expr -> op == expr_encode_int8 ||
3047 		expr -> op == expr_encode_int16 ||
3048 		expr -> op == expr_encode_int32 ||
3049 		expr -> op == expr_binary_to_ascii ||
3050 		expr -> op == expr_reverse ||
3051 		expr -> op == expr_pick_first_value ||
3052 		expr -> op == expr_config_option ||
3053 		expr -> op == expr_extract_int8 ||
3054 		expr -> op == expr_extract_int16 ||
3055 		expr -> op == expr_extract_int32 ||
3056 		expr -> op == expr_v6relay);
3057 }
3058 
3059 static int op_val (enum expr_op);
3060 
3061 static int op_val (op)
3062 	enum expr_op op;
3063 {
3064 	switch (op) {
3065 	      case expr_none:
3066 	      case expr_match:
3067 	      case expr_static:
3068 	      case expr_check:
3069 	      case expr_substring:
3070 	      case expr_suffix:
3071 	      case expr_lcase:
3072 	      case expr_ucase:
3073 	      case expr_concat:
3074 	      case expr_encapsulate:
3075 	      case expr_host_lookup:
3076 	      case expr_not:
3077 	      case expr_option:
3078 	      case expr_hardware:
3079 	      case expr_packet:
3080 	      case expr_const_data:
3081 	      case expr_extract_int8:
3082 	      case expr_extract_int16:
3083 	      case expr_extract_int32:
3084 	      case expr_encode_int8:
3085 	      case expr_encode_int16:
3086 	      case expr_encode_int32:
3087 	      case expr_const_int:
3088 	      case expr_exists:
3089 	      case expr_variable_exists:
3090 	      case expr_known:
3091 	      case expr_binary_to_ascii:
3092 	      case expr_reverse:
3093 	      case expr_filename:
3094 	      case expr_sname:
3095 	      case expr_pick_first_value:
3096 	      case expr_host_decl_name:
3097 	      case expr_config_option:
3098 	      case expr_leased_address:
3099 	      case expr_lease_time:
3100 	      case expr_dns_transaction:
3101 	      case expr_null:
3102 	      case expr_variable_reference:
3103 	      case expr_ns_add:
3104 	      case expr_ns_delete:
3105 	      case expr_ns_exists:
3106 	      case expr_ns_not_exists:
3107 	      case expr_arg:
3108 	      case expr_funcall:
3109 	      case expr_function:
3110 		/* XXXDPN: Need to assign sane precedences to these. */
3111 	      case expr_binary_and:
3112 	      case expr_binary_or:
3113 	      case expr_binary_xor:
3114 	      case expr_client_state:
3115 	      case expr_gethostname:
3116 	      case expr_v6relay:
3117 		return 100;
3118 
3119 	      case expr_equal:
3120 	      case expr_not_equal:
3121 	      case expr_regex_match:
3122 	      case expr_iregex_match:
3123 		return 4;
3124 
3125 	      case expr_or:
3126 	      case expr_and:
3127 		return 3;
3128 
3129 	      case expr_add:
3130 	      case expr_subtract:
3131 		return 2;
3132 
3133 	      case expr_multiply:
3134 	      case expr_divide:
3135 	      case expr_remainder:
3136 		return 1;
3137 	}
3138 	return 100;
3139 }
3140 
3141 int op_precedence (op1, op2)
3142 	enum expr_op op1, op2;
3143 {
3144 	return op_val (op1) - op_val (op2);
3145 }
3146 
3147 enum expression_context expression_context (struct expression *expr)
3148 {
3149 	if (is_data_expression (expr))
3150 		return context_data;
3151 	if (is_numeric_expression (expr))
3152 		return context_numeric;
3153 	if (is_boolean_expression (expr))
3154 		return context_boolean;
3155 	return context_any;
3156 }
3157 
3158 enum expression_context op_context (op)
3159 	enum expr_op op;
3160 {
3161 	switch (op) {
3162 /* XXX Why aren't these specific? */
3163 	      case expr_none:
3164 	      case expr_match:
3165 	      case expr_static:
3166 	      case expr_check:
3167 	      case expr_substring:
3168 	      case expr_suffix:
3169 	      case expr_lcase:
3170 	      case expr_ucase:
3171 	      case expr_concat:
3172 	      case expr_encapsulate:
3173 	      case expr_host_lookup:
3174 	      case expr_not:
3175 	      case expr_option:
3176 	      case expr_hardware:
3177 	      case expr_packet:
3178 	      case expr_const_data:
3179 	      case expr_extract_int8:
3180 	      case expr_extract_int16:
3181 	      case expr_extract_int32:
3182 	      case expr_encode_int8:
3183 	      case expr_encode_int16:
3184 	      case expr_encode_int32:
3185 	      case expr_const_int:
3186 	      case expr_exists:
3187 	      case expr_variable_exists:
3188 	      case expr_known:
3189 	      case expr_binary_to_ascii:
3190 	      case expr_reverse:
3191 	      case expr_filename:
3192 	      case expr_sname:
3193 	      case expr_pick_first_value:
3194 	      case expr_host_decl_name:
3195 	      case expr_config_option:
3196 	      case expr_leased_address:
3197 	      case expr_lease_time:
3198 	      case expr_null:
3199 	      case expr_variable_reference:
3200 	      case expr_ns_add:
3201 	      case expr_ns_delete:
3202 	      case expr_ns_exists:
3203 	      case expr_ns_not_exists:
3204 	      case expr_dns_transaction:
3205 	      case expr_arg:
3206 	      case expr_funcall:
3207 	      case expr_function:
3208 	      case expr_gethostname:
3209 	      case expr_v6relay:
3210 		return context_any;
3211 
3212 	      case expr_equal:
3213 	      case expr_not_equal:
3214 	      case expr_regex_match:
3215 	      case expr_iregex_match:
3216 		return context_data;
3217 
3218 	      case expr_and:
3219 		return context_boolean;
3220 
3221 	      case expr_or:
3222 		return context_boolean;
3223 
3224 	      case expr_add:
3225 	      case expr_subtract:
3226 	      case expr_multiply:
3227 	      case expr_divide:
3228 	      case expr_remainder:
3229 	      case expr_binary_and:
3230 	      case expr_binary_or:
3231 	      case expr_binary_xor:
3232 	      case expr_client_state:
3233 		return context_numeric;
3234 	}
3235 	return context_any;
3236 }
3237 
3238 int write_expression (file, expr, col, indent, firstp)
3239 	FILE *file;
3240 	struct expression *expr;
3241 	int col;
3242 	int indent;
3243 	int firstp;
3244 {
3245 	struct expression *e;
3246 	const char *s;
3247 	char obuf [65];
3248 	int scol;
3249 	int width;
3250 
3251 	/* If this promises to be a fat expression, start a new line. */
3252 	if (!firstp && is_compound_expression (expr)) {
3253 		indent_spaces (file, indent);
3254 		col = indent;
3255 	}
3256 
3257 	switch (expr -> op) {
3258 	      case expr_none:
3259 		col = token_print_indent (file, col, indent, "", "", "null");
3260 		break;
3261 
3262 	      case expr_check:
3263 		col = token_print_indent (file, col, indent, "", "", "check");
3264 		col = token_print_indent_concat (file, col, indent,
3265 						 " ", "", "\"",
3266 						 expr -> data.check -> name,
3267 						 "\"", (char *)0);
3268 		break;
3269 
3270 	      case expr_regex_match:
3271 		s = "~=";
3272 		goto binary;
3273 
3274 	      case expr_iregex_match:
3275 		s = "~~";
3276 		goto binary;
3277 
3278 	      case expr_not_equal:
3279 		s = "!=";
3280 		goto binary;
3281 
3282 	      case expr_equal:
3283 		s = "=";
3284 	      binary:
3285 		col = write_expression (file, expr -> data.equal [0],
3286 					col, indent, 1);
3287 		col = token_print_indent (file, col, indent, " ", " ", s);
3288 		col = write_expression (file, expr -> data.equal [1],
3289 					col, indent + 2, 0);
3290 		break;
3291 
3292 	      case expr_substring:
3293 		col = token_print_indent (file, col, indent, "", "",
3294 					  "substring");
3295 		col = token_print_indent (file, col, indent, " ", "", "(");
3296 		scol = col;
3297 		col = write_expression (file, expr -> data.substring.expr,
3298 					col, scol, 1);
3299 		col = token_print_indent (file, col, indent, "", " ", ",");
3300 		col = write_expression (file, expr -> data.substring.offset,
3301 					col, indent, 0);
3302 		col = token_print_indent (file, col, scol, "", " ", ",");
3303 		col = write_expression (file, expr -> data.substring.len,
3304 					col, scol, 0);
3305 		col = token_print_indent (file, col, indent, "", "", ")");
3306 		break;
3307 
3308 	      case expr_suffix:
3309 		col = token_print_indent (file, col, indent, "", "", "suffix");
3310 		col = token_print_indent (file, col, indent, " ", "", "(");
3311 		scol = col;
3312 		col = write_expression (file, expr -> data.suffix.expr,
3313 					col, scol, 1);
3314 		col = token_print_indent (file, col, scol, "", " ", ",");
3315 		col = write_expression (file, expr -> data.suffix.len,
3316 					col, scol, 0);
3317 		col = token_print_indent (file, col, indent, "", "", ")");
3318 		break;
3319 
3320 	      case expr_lcase:
3321 		col = token_print_indent(file, col, indent, "", "", "lcase");
3322 		col = token_print_indent(file, col, indent, " ", "", "(");
3323 		scol = col;
3324 		col = write_expression(file, expr->data.lcase, col, scol, 1);
3325 		col = token_print_indent(file, col, indent, "", "", ")");
3326 		break;
3327 
3328 	      case expr_ucase:
3329 		col = token_print_indent(file, col, indent, "", "", "ucase");
3330 		col = token_print_indent(file, col, indent, " ", "", "(");
3331 		scol = col;
3332 		col = write_expression(file, expr->data.ucase, col, scol, 1);
3333 		col = token_print_indent(file, col, indent, "", "", ")");
3334 		break;
3335 
3336 	      case expr_concat:
3337 		e = expr;
3338 		col = token_print_indent (file, col, indent, "", "",
3339 					  "concat");
3340 		col = token_print_indent (file, col, indent, " ", "", "(");
3341 		scol = col;
3342 		firstp = 1;
3343 	      concat_again:
3344 		col = write_expression (file, e -> data.concat [0],
3345 					col, scol, firstp);
3346 		firstp = 0;
3347 		if (!e -> data.concat [1])
3348 			goto no_concat_cdr;
3349 		col = token_print_indent (file, col, scol, "", " ", ",");
3350 		if (e -> data.concat [1] -> op == expr_concat) {
3351 			e = e -> data.concat [1];
3352 			goto concat_again;
3353 		}
3354 		col = write_expression (file, e -> data.concat [1],
3355 					col, scol, 0);
3356 	      no_concat_cdr:
3357 		col = token_print_indent (file, col, indent, "", "", ")");
3358 		break;
3359 
3360 	      case expr_host_lookup:
3361 		col = token_print_indent (file, col, indent, "", "",
3362 					  "gethostbyname");
3363 		col = token_print_indent (file, col, indent, " ", "", "(");
3364 		col = token_print_indent_concat
3365 			(file, col, indent, "", "",
3366 			 "\"", expr -> data.host_lookup -> hostname, "\"",
3367 			 (char *)0);
3368 		col = token_print_indent (file, col, indent, "", "", ")");
3369 		break;
3370 
3371 	      case expr_add:
3372 		s = "+";
3373 		goto binary;
3374 
3375 	      case expr_subtract:
3376 		s = "-";
3377 		goto binary;
3378 
3379 	      case expr_multiply:
3380 		s = "*";
3381 		goto binary;
3382 
3383 	      case expr_divide:
3384 		s = "/";
3385 		goto binary;
3386 
3387 	      case expr_remainder:
3388 		s = "%";
3389 		goto binary;
3390 
3391 	      case expr_binary_and:
3392 		s = "&";
3393 		goto binary;
3394 
3395 	      case expr_binary_or:
3396 		s = "|";
3397 		goto binary;
3398 
3399 	      case expr_binary_xor:
3400 		s = "^";
3401 		goto binary;
3402 
3403 	      case expr_and:
3404 		s = "and";
3405 		goto binary;
3406 
3407 	      case expr_or:
3408 		s = "or";
3409 		goto binary;
3410 
3411 	      case expr_not:
3412 		col = token_print_indent (file, col, indent, "", " ", "not");
3413 		col = write_expression (file,
3414 					expr -> data.not, col, indent + 2, 1);
3415 		break;
3416 
3417 	      case expr_option:
3418 		s = "option";
3419 
3420 	      print_option_name:
3421 		col = token_print_indent (file, col, indent, "", "", s);
3422 
3423 		if (expr -> data.option -> universe != &dhcp_universe) {
3424 			col = token_print_indent (file, col, indent,
3425 						  " ", "",
3426 						  (expr -> data.option ->
3427 						   universe -> name));
3428 			col = token_print_indent (file, col, indent, "", "",
3429 						  ".");
3430 			col = token_print_indent (file, col, indent, "", "",
3431 						  expr -> data.option -> name);
3432 		} else {
3433 			col = token_print_indent (file, col, indent, " ", "",
3434 						  expr -> data.option -> name);
3435 		}
3436 		break;
3437 
3438 	      case expr_hardware:
3439 		col = token_print_indent (file, col, indent, "", "",
3440 					  "hardware");
3441 		break;
3442 
3443 	      case expr_packet:
3444 		col = token_print_indent (file, col, indent, "", "",
3445 					  "packet");
3446 		col = token_print_indent (file, col, indent, " ", "", "(");
3447 		scol = col;
3448 		col = write_expression (file, expr -> data.packet.offset,
3449 					col, indent, 1);
3450 		col = token_print_indent (file, col, scol, "", " ", ",");
3451 		col = write_expression (file, expr -> data.packet.len,
3452 					col, scol, 0);
3453 		col = token_print_indent (file, col, indent, "", "", ")");
3454 		break;
3455 
3456 	      case expr_const_data:
3457 		col = token_indent_data_string (file, col, indent, "", "",
3458 						&expr -> data.const_data);
3459 		break;
3460 
3461 	      case expr_extract_int8:
3462 		width = 8;
3463 	      extract_int:
3464 		col = token_print_indent (file, col, indent, "", "",
3465 					  "extract-int");
3466 		col = token_print_indent (file, col, indent, " ", "", "(");
3467 		scol = col;
3468 		col = write_expression (file, expr -> data.extract_int,
3469 					col, indent, 1);
3470 		col = token_print_indent (file, col, scol, "", " ", ",");
3471 		sprintf (obuf, "%d", width);
3472 		col = token_print_indent (file, col, scol, " ", "", obuf);
3473 		col = token_print_indent (file, col, indent, "", "", ")");
3474 		break;
3475 
3476 	      case expr_extract_int16:
3477 		width = 16;
3478 		goto extract_int;
3479 
3480 	      case expr_extract_int32:
3481 		width = 32;
3482 		goto extract_int;
3483 
3484 	      case expr_encode_int8:
3485 		width = 8;
3486 	      encode_int:
3487 		col = token_print_indent (file, col, indent, "", "",
3488 					  "encode-int");
3489 		col = token_print_indent (file, col, indent, " ", "", "(");
3490 		scol = col;
3491 		col = write_expression (file, expr -> data.extract_int,
3492 					col, indent, 1);
3493 		col = token_print_indent (file, col, scol, "", " ", ",");
3494 		sprintf (obuf, "%d", width);
3495 		col = token_print_indent (file, col, scol, " ", "", obuf);
3496 		col = token_print_indent (file, col, indent, "", "",
3497 					  ")");
3498 		break;
3499 
3500 	      case expr_encode_int16:
3501 		width = 16;
3502 		goto encode_int;
3503 
3504 	      case expr_encode_int32:
3505 		width = 32;
3506 		goto encode_int;
3507 
3508 	      case expr_const_int:
3509 		sprintf (obuf, "%lu", expr -> data.const_int);
3510 		col = token_print_indent (file, col, indent, "", "", obuf);
3511 		break;
3512 
3513 	      case expr_exists:
3514 		s = "exists";
3515 		goto print_option_name;
3516 
3517 	      case expr_encapsulate:
3518 		col = token_print_indent (file, col, indent, "", "",
3519 					  "encapsulate");
3520 		col = token_indent_data_string (file, col, indent, " ", "",
3521 						&expr -> data.encapsulate);
3522 		break;
3523 
3524 	      case expr_known:
3525 		col = token_print_indent (file, col, indent, "", "", "known");
3526 		break;
3527 
3528 	      case expr_reverse:
3529 		col = token_print_indent (file, col, indent, "", "",
3530 					  "reverse");
3531 		col = token_print_indent (file, col, indent, " ", "", "(");
3532 		scol = col;
3533 		col = write_expression (file, expr -> data.reverse.width,
3534 					col, scol, 1);
3535 		col = token_print_indent (file, col, scol, "", " ", ",");
3536 		col = write_expression (file, expr -> data.reverse.buffer,
3537 					col, scol, 0);
3538 		col = token_print_indent (file, col, indent, "", "",
3539 					  ")");
3540 		break;
3541 
3542 	      case expr_leased_address:
3543 		col = token_print_indent (file, col, indent, "", "",
3544 					  "leased-address");
3545 		break;
3546 
3547 	      case expr_client_state:
3548 		col = token_print_indent (file, col, indent, "", "",
3549 					  "client-state");
3550 		break;
3551 
3552 	      case expr_binary_to_ascii:
3553 		col = token_print_indent (file, col, indent, "", "",
3554 					  "binary-to-ascii");
3555 		col = token_print_indent (file, col, indent, " ", "",
3556 					  "(");
3557 		scol = col;
3558 		col = write_expression (file, expr -> data.b2a.base,
3559 					col, scol, 1);
3560 		col = token_print_indent (file, col, scol, "", " ",
3561 					  ",");
3562 		col = write_expression (file, expr -> data.b2a.width,
3563 					col, scol, 0);
3564 		col = token_print_indent (file, col, scol, "", " ",
3565 					  ",");
3566 		col = write_expression (file, expr -> data.b2a.separator,
3567 					col, scol, 0);
3568 		col = token_print_indent (file, col, scol, "", " ",
3569 					  ",");
3570 		col = write_expression (file, expr -> data.b2a.buffer,
3571 					col, scol, 0);
3572 		col = token_print_indent (file, col, indent, "", "",
3573 					  ")");
3574 		break;
3575 
3576 	      case expr_config_option:
3577 		s = "config-option";
3578 		goto print_option_name;
3579 
3580 	      case expr_host_decl_name:
3581 		col = token_print_indent (file, col, indent, "", "",
3582 					  "host-decl-name");
3583 		break;
3584 
3585 	      case expr_pick_first_value:
3586 		e = expr;
3587 		col = token_print_indent (file, col, indent, "", "",
3588 					  "concat");
3589 		col = token_print_indent (file, col, indent, " ", "",
3590 					  "(");
3591 		scol = col;
3592 		firstp = 1;
3593 	      pick_again:
3594 		col = write_expression (file,
3595 					e -> data.pick_first_value.car,
3596 					col, scol, firstp);
3597 		firstp = 0;
3598 		/* We're being very lisp-like right now - instead of
3599                    representing this expression as (first middle . last) we're
3600                    representing it as (first middle last), which means that the
3601                    tail cdr is always nil.  Apologies to non-wisp-lizards - may
3602                    this obscure way of describing the problem motivate you to
3603                    learn more about the one true computing language. */
3604 		if (!e -> data.pick_first_value.cdr)
3605 			goto no_pick_cdr;
3606 		col = token_print_indent (file, col, scol, "", " ",
3607 					  ",");
3608 		if (e -> data.pick_first_value.cdr -> op ==
3609 		    expr_pick_first_value) {
3610 			e = e -> data.pick_first_value.cdr;
3611 			goto pick_again;
3612 		}
3613 		col = write_expression (file,
3614 					e -> data.pick_first_value.cdr,
3615 					col, scol, 0);
3616 	      no_pick_cdr:
3617 		col = token_print_indent (file, col, indent, "", "",
3618 					  ")");
3619 		break;
3620 
3621 	      case expr_lease_time:
3622 		col = token_print_indent (file, col, indent, "", "",
3623 					  "lease-time");
3624 		break;
3625 
3626 	      case expr_static:
3627 		col = token_print_indent (file, col, indent, "", "",
3628 					  "static");
3629 		break;
3630 
3631 	      case expr_null:
3632 		col = token_print_indent (file, col, indent, "", "", "null");
3633 		break;
3634 
3635 	      case expr_variable_reference:
3636 		col = token_print_indent (file, indent, indent, "", "",
3637 					  expr -> data.variable);
3638 		break;
3639 
3640 	      case expr_variable_exists:
3641 		col = token_print_indent (file, indent, indent, "", "",
3642 					  "defined");
3643 		col = token_print_indent (file, col, indent, " ", "", "(");
3644 		col = token_print_indent (file, col, indent, "", "",
3645 					  expr -> data.variable);
3646 		col = token_print_indent (file, col, indent, "", "", ")");
3647 		break;
3648 
3649 	      case expr_gethostname:
3650 		col = token_print_indent(file, col, indent, "", "",
3651 					 "gethostname()");
3652 		break;
3653 
3654 	      case expr_funcall:
3655 		col = token_print_indent(file, indent, indent, "", "",
3656 					 expr->data.funcall.name);
3657 		col = token_print_indent(file, col, indent, " ", "", "(");
3658 
3659 		firstp = 1;
3660 		e = expr->data.funcall.arglist;
3661 		while (e != NULL) {
3662 			if (!firstp)
3663 				col = token_print_indent(file, col, indent,
3664 							 "", " ", ",");
3665 
3666 			col = write_expression(file, e->data.arg.val, col,
3667 					       indent, firstp);
3668 			firstp = 0;
3669 			e = e->data.arg.next;
3670 		}
3671 
3672 		col = token_print_indent(file, col, indent, "", "", ")");
3673 		break;
3674 
3675 	      case expr_v6relay:
3676 		col = token_print_indent(file, col, indent, "", "",
3677 					 "v6relay");
3678 		col = token_print_indent(file, col, indent, " ", "", "(");
3679 		scol = col;
3680 		col = write_expression(file, expr->data.v6relay.relay,
3681 				       col, scol, 1);
3682 		col = token_print_indent (file, col, scol, "", " ", ",");
3683 		col = write_expression(file, expr->data.v6relay.roption,
3684 				       col, scol, 0);
3685 		col = token_print_indent(file, col, indent, "", "", ")");
3686 		break;
3687 
3688 	      default:
3689 		log_fatal ("invalid expression type in print_expression: %d",
3690 			   expr -> op);
3691 	}
3692 	return col;
3693 }
3694 
3695 struct binding *find_binding (struct binding_scope *scope, const char *name)
3696 {
3697 	struct binding *bp;
3698 	struct binding_scope *s;
3699 
3700 	for (s = scope; s; s = s -> outer) {
3701 		for (bp = s -> bindings; bp; bp = bp -> next) {
3702 			if (!strcasecmp (name, bp -> name)) {
3703 				return bp;
3704 			}
3705 		}
3706 	}
3707 	return (struct binding *)0;
3708 }
3709 
3710 int free_bindings (struct binding_scope *scope, const char *file, int line)
3711 {
3712 	struct binding *bp, *next;
3713 
3714 	for (bp = scope -> bindings; bp; bp = next) {
3715 		next = bp -> next;
3716 		if (bp -> name)
3717 			dfree (bp -> name, file, line);
3718 		if (bp -> value)
3719 			binding_value_dereference (&bp -> value, file, line);
3720 		dfree (bp, file, line);
3721 	}
3722 	scope -> bindings = (struct binding *)0;
3723 	return 1;
3724 }
3725 
3726 int binding_scope_dereference (ptr, file, line)
3727 	struct binding_scope **ptr;
3728 	const char *file;
3729 	int line;
3730 {
3731 	struct binding_scope *binding_scope;
3732 
3733 	if (!ptr || !*ptr) {
3734 		log_error ("%s(%d): null pointer", file, line);
3735 #if defined (POINTER_DEBUG)
3736 		abort ();
3737 #else
3738 		return 0;
3739 #endif
3740 	}
3741 
3742 	binding_scope = *ptr;
3743 	*ptr = (struct binding_scope *)0;
3744 	--binding_scope -> refcnt;
3745 	rc_register (file, line, ptr,
3746 		     binding_scope, binding_scope -> refcnt, 1, RC_MISC);
3747 	if (binding_scope -> refcnt > 0)
3748 		return 1;
3749 
3750 	if (binding_scope -> refcnt < 0) {
3751 		log_error ("%s(%d): negative refcnt!", file, line);
3752 #if defined (DEBUG_RC_HISTORY)
3753 		dump_rc_history (binding_scope);
3754 #endif
3755 #if defined (POINTER_DEBUG)
3756 		abort ();
3757 #else
3758 		return 0;
3759 #endif
3760 	}
3761 
3762 	free_bindings (binding_scope, file, line);
3763 	if (binding_scope -> outer)
3764 		binding_scope_dereference (&binding_scope -> outer, MDL);
3765 	dfree (binding_scope, file, line);
3766 	return 1;
3767 }
3768 
3769 int fundef_dereference (ptr, file, line)
3770 	struct fundef **ptr;
3771 	const char *file;
3772 	int line;
3773 {
3774 	struct fundef *bp;
3775 	struct string_list *sp, *next;
3776 
3777 	if ((ptr == NULL) || (*ptr == NULL)) {
3778 		log_error ("%s(%d): null pointer", file, line);
3779 #if defined (POINTER_DEBUG)
3780 		abort ();
3781 #else
3782 		return 0;
3783 #endif
3784 	}
3785 
3786 	bp = *ptr;
3787 	bp -> refcnt--;
3788 	rc_register (file, line, ptr, bp, bp -> refcnt, 1, RC_MISC);
3789 	if (bp -> refcnt < 0) {
3790 		log_error ("%s(%d): negative refcnt!", file, line);
3791 #if defined (DEBUG_RC_HISTORY)
3792 		dump_rc_history (bp);
3793 #endif
3794 #if defined (POINTER_DEBUG)
3795 		abort ();
3796 #else
3797 		return 0;
3798 #endif
3799 	}
3800 	if (!bp -> refcnt) {
3801 		for (sp = bp -> args; sp; sp = next) {
3802 			next = sp -> next;
3803 			dfree (sp, file, line);
3804 		}
3805 		if (bp -> statements)
3806 			executable_statement_dereference (&bp -> statements,
3807 							  file, line);
3808 		dfree (bp, file, line);
3809 	}
3810 	*ptr = (struct fundef *)0;
3811 	return 1;
3812 }
3813 
3814 #if defined (NOTYET)		/* Post 3.0 final. */
3815 int data_subexpression_length (int *rv,
3816 			       struct expression *expr)
3817 {
3818 	int crhs, clhs, llhs, lrhs;
3819 	switch (expr -> op) {
3820 	      case expr_substring:
3821 		if (expr -> data.substring.len &&
3822 		    expr -> data.substring.len -> op == expr_const_int) {
3823 			(*rv =
3824 			 (int)expr -> data.substring.len -> data.const_int);
3825 			return 1;
3826 		}
3827 		return 0;
3828 
3829 	      case expr_packet:
3830 	      case expr_suffix:
3831 		if (expr -> data.suffix.len &&
3832 		    expr -> data.suffix.len -> op == expr_const_int) {
3833 			(*rv =
3834 			 (int)expr -> data.suffix.len -> data.const_int);
3835 			return 1;
3836 		}
3837 		return 0;
3838 
3839 	      case expr_lcase:
3840 		return data_subexpression_length(rv, expr->data.lcase);
3841 
3842 	      case expr_ucase:
3843 		return data_subexpression_length(rv, expr->data.ucase);
3844 
3845 	      case expr_concat:
3846 		clhs = data_subexpression_length (&llhs,
3847 						  expr -> data.concat [0]);
3848 		crhs = data_subexpression_length (&lrhs,
3849 						  expr -> data.concat [1]);
3850 		if (crhs == 0 || clhs == 0)
3851 			return 0;
3852 		*rv = llhs + lrhs;
3853 		return 1;
3854 		break;
3855 
3856 	      case expr_hardware:
3857 		return 0;
3858 
3859 	      case expr_const_data:
3860 		*rv = expr -> data.const_data.len;
3861 		return 2;
3862 
3863 	      case expr_reverse:
3864 		return data_subexpression_length (rv,
3865 						  expr -> data.reverse.buffer);
3866 
3867 	      case expr_leased_address:
3868 	      case expr_lease_time:
3869 		*rv = 4;
3870 		return 2;
3871 
3872 	      case expr_pick_first_value:
3873 		clhs = data_subexpression_length (&llhs,
3874 						  expr -> data.concat [0]);
3875 		crhs = data_subexpression_length (&lrhs,
3876 						  expr -> data.concat [1]);
3877 		if (crhs == 0 || clhs == 0)
3878 			return 0;
3879 		if (llhs > lrhs)
3880 			*rv = llhs;
3881 		else
3882 			*rv = lrhs;
3883 		return 1;
3884 
3885 	      case expr_v6relay:
3886 		clhs = data_subexpression_length (&llhs,
3887 						  expr -> data.v6relay.relay);
3888 		crhs = data_subexpression_length (&lrhs,
3889 						  expr -> data.v6relay.roption);
3890 		if (crhs == 0 || clhs == 0)
3891 			return 0;
3892 		*rv = llhs + lrhs;
3893 		return 1;
3894 		break;
3895 
3896 	      case expr_binary_to_ascii:
3897 	      case expr_config_option:
3898 	      case expr_host_decl_name:
3899 	      case expr_encapsulate:
3900 	      case expr_filename:
3901 	      case expr_sname:
3902 	      case expr_host_lookup:
3903 	      case expr_option:
3904 	      case expr_none:
3905 	      case expr_match:
3906 	      case expr_check:
3907 	      case expr_equal:
3908 	      case expr_regex_match:
3909 	      case expr_iregex_match:
3910 	      case expr_and:
3911 	      case expr_or:
3912 	      case expr_not:
3913 	      case expr_extract_int8:
3914 	      case expr_extract_int16:
3915 	      case expr_extract_int32:
3916 	      case expr_encode_int8:
3917 	      case expr_encode_int16:
3918 	      case expr_encode_int32:
3919 	      case expr_const_int:
3920 	      case expr_exists:
3921 	      case expr_known:
3922 	      case expr_static:
3923 	      case expr_not_equal:
3924 	      case expr_null:
3925 	      case expr_variable_exists:
3926 	      case expr_variable_reference:
3927 	      case expr_arg:
3928 	      case expr_funcall:
3929 	      case expr_function:
3930 	      case expr_add:
3931 	      case expr_subtract:
3932 	      case expr_multiply:
3933 	      case expr_divide:
3934 	      case expr_remainder:
3935 	      case expr_binary_and:
3936 	      case expr_binary_or:
3937 	      case expr_binary_xor:
3938 	      case expr_client_state:
3939 	      case expr_gethostname:
3940 		return 0;
3941 	}
3942 	return 0;
3943 }
3944 
3945 int expr_valid_for_context (struct expression *expr,
3946 			    enum expression_context context)
3947 {
3948 	/* We don't know at parse time what type of value a function may
3949 	   return, so we can't flag an error on it. */
3950 	if (expr -> op == expr_funcall ||
3951 	    expr -> op == expr_variable_reference)
3952 		return 1;
3953 
3954 	switch (context) {
3955 	      case context_any:
3956 		return 1;
3957 
3958 	      case context_boolean:
3959 		if (is_boolean_expression (expr))
3960 			return 1;
3961 		return 0;
3962 
3963 	      case context_data:
3964 		if (is_data_expression (expr))
3965 			return 1;
3966 		return 0;
3967 
3968 	      case context_numeric:
3969 		if (is_numeric_expression (expr))
3970 			return 1;
3971 		return 0;
3972 
3973 	      case context_data_or_numeric:
3974 		if (is_numeric_expression (expr) ||
3975 		    is_data_expression (expr)) {
3976 			return 1;
3977 		}
3978 		return 0;
3979 
3980 	      case context_function:
3981 		if (expr -> op == expr_function)
3982 			return 1;
3983 		return 0;
3984 	}
3985 	return 0;
3986 }
3987 #endif /* NOTYET */
3988 
3989 struct binding *create_binding (struct binding_scope **scope, const char *name)
3990 {
3991 	struct binding *binding;
3992 
3993 	if (!*scope) {
3994 		if (!binding_scope_allocate (scope, MDL))
3995 			return (struct binding *)0;
3996 	}
3997 
3998 	binding = find_binding (*scope, name);
3999 	if (!binding) {
4000 		binding = dmalloc (sizeof *binding, MDL);
4001 		if (!binding)
4002 			return (struct binding *)0;
4003 
4004 		memset (binding, 0, sizeof *binding);
4005 		binding -> name = dmalloc (strlen (name) + 1, MDL);
4006 		if (!binding -> name) {
4007 			dfree (binding, MDL);
4008 			return (struct binding *)0;
4009 		}
4010 		strcpy (binding -> name, name);
4011 
4012 		binding -> next = (*scope) -> bindings;
4013 		(*scope) -> bindings = binding;
4014 	}
4015 
4016 	return binding;
4017 }
4018 
4019 
4020 int bind_ds_value (struct binding_scope **scope,
4021 		   const char *name,
4022 		   struct data_string *value)
4023 {
4024 	struct binding *binding;
4025 
4026 	binding = create_binding (scope, name);
4027 	if (!binding)
4028 		return 0;
4029 
4030 	if (binding -> value)
4031 		binding_value_dereference (&binding -> value, MDL);
4032 
4033 	if (!binding_value_allocate (&binding -> value, MDL))
4034 		return 0;
4035 
4036 	data_string_copy (&binding -> value -> value.data, value, MDL);
4037 	binding -> value -> type = binding_data;
4038 
4039 	return 1;
4040 }
4041 
4042 
4043 int find_bound_string (struct data_string *value,
4044 		       struct binding_scope *scope,
4045 		       const char *name)
4046 {
4047 	struct binding *binding;
4048 
4049 	binding = find_binding (scope, name);
4050 	if (!binding ||
4051 	    !binding -> value ||
4052 	    binding -> value -> type != binding_data)
4053 		return 0;
4054 
4055 	if (binding -> value -> value.data.terminated) {
4056 		data_string_copy (value, &binding -> value -> value.data, MDL);
4057 	} else {
4058 		if (buffer_allocate (&value->buffer,
4059 				     binding->value->value.data.len,
4060 				     MDL) == 0) {
4061 			return 0;
4062 		}
4063 
4064 		memcpy (value -> buffer -> data,
4065 			binding -> value -> value.data.data,
4066 			binding -> value -> value.data.len);
4067 		value -> data = value -> buffer -> data;
4068 		value -> len = binding -> value -> value.data.len;
4069 	}
4070 
4071 	return 1;
4072 }
4073 
4074 int unset (struct binding_scope *scope, const char *name)
4075 {
4076 	struct binding *binding;
4077 
4078 	binding = find_binding (scope, name);
4079 	if (binding) {
4080 		if (binding -> value)
4081 			binding_value_dereference
4082 				(&binding -> value, MDL);
4083 		return 1;
4084 	}
4085 	return 0;
4086 }
4087 
4088 /* vim: set tabstop=8: */
4089