3 Routines for manipulating parse trees... */
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
36 static char copyright
[] =
37 "$Id: tree.c,v 1.101.2.11 2004/11/24 17:39:16 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
41 #include <omapip/omapip_p.h>
43 struct binding_scope
*global_scope
;
45 static int do_host_lookup
PROTO ((struct data_string
*,
46 struct dns_host_entry
*));
49 struct __res_state resolver_state
;
50 int resolver_inited
= 0;
57 pair foo
= (pair
)dmalloc (sizeof *foo
, MDL
);
59 log_fatal ("no memory for cons.");
65 int make_const_option_cache (oc
, buffer
, data
, len
, option
, file
, line
)
66 struct option_cache
**oc
;
67 struct buffer
**buffer
;
70 struct option
*option
;
80 bp
= (struct buffer
*)0;
81 if (!buffer_allocate (&bp
, len
, file
, line
)) {
82 log_error ("%s(%d): can't allocate buffer.",
88 if (!option_cache_allocate (oc
, file
, line
)) {
89 log_error ("%s(%d): can't allocate option cache.", file
, line
);
90 buffer_dereference (&bp
, file
, line
);
94 (*oc
) -> data
.len
= len
;
95 (*oc
) -> data
.buffer
= bp
;
96 (*oc
) -> data
.data
= &bp
-> data
[0];
97 (*oc
) -> data
.terminated
= 0;
99 memcpy (&bp
-> data
[0], data
, len
);
100 (*oc
) -> option
= option
;
104 int make_host_lookup (expr
, name
)
105 struct expression
**expr
;
108 if (!expression_allocate (expr
, MDL
)) {
109 log_error ("No memory for host lookup tree node.");
112 (*expr
) -> op
= expr_host_lookup
;
113 if (!enter_dns_host (&((*expr
) -> data
.host_lookup
), name
)) {
114 expression_dereference (expr
, MDL
);
120 int enter_dns_host (dh
, name
)
121 struct dns_host_entry
**dh
;
124 /* XXX This should really keep a hash table of hostnames
125 XXX and just add a new reference to a hostname that
126 XXX already exists, if possible, rather than creating
127 XXX a new structure. */
128 if (!dns_host_entry_allocate (dh
, name
, MDL
)) {
129 log_error ("Can't allocate space for new host.");
135 int make_const_data (struct expression
**expr
, const unsigned char *data
,
136 unsigned len
, int terminated
, int allocate
,
137 const char *file
, int line
)
139 struct expression
*nt
;
141 if (!expression_allocate (expr
, file
, line
)) {
142 log_error ("No memory for make_const_data tree node.");
149 if (!buffer_allocate (&nt
-> data
.const_data
.buffer
,
150 len
+ terminated
, file
, line
)) {
151 log_error ("Can't allocate const_data buffer");
152 expression_dereference (expr
, file
, line
);
155 nt
-> data
.const_data
.data
=
156 &nt
-> data
.const_data
.buffer
-> data
[0];
157 memcpy (nt
-> data
.const_data
.buffer
-> data
,
158 data
, len
+ terminated
);
160 nt
-> data
.const_data
.data
= data
;
161 nt
-> data
.const_data
.terminated
= terminated
;
163 nt
-> data
.const_data
.data
= 0;
165 nt
-> op
= expr_const_data
;
166 nt
-> data
.const_data
.len
= len
;
170 int make_const_int (expr
, val
)
171 struct expression
**expr
;
174 if (!expression_allocate (expr
, MDL
)) {
175 log_error ("No memory for make_const_int tree node.");
179 (*expr
) -> op
= expr_const_int
;
180 (*expr
) -> data
.const_int
= val
;
184 int make_concat (expr
, left
, right
)
185 struct expression
**expr
;
186 struct expression
*left
, *right
;
188 /* If we're concatenating a null tree to a non-null tree, just
189 return the non-null tree; if both trees are null, return
194 expression_reference (expr
, right
, MDL
);
198 expression_reference (expr
, left
, MDL
);
202 /* Otherwise, allocate a new node to concatenate the two. */
203 if (!expression_allocate (expr
, MDL
)) {
204 log_error ("No memory for concatenation expression node.");
208 (*expr
) -> op
= expr_concat
;
209 expression_reference (&(*expr
) -> data
.concat
[0], left
, MDL
);
210 expression_reference (&(*expr
) -> data
.concat
[1], right
, MDL
);
214 int make_encapsulation (expr
, name
)
215 struct expression
**expr
;
216 struct data_string
*name
;
218 /* Allocate a new node to store the encapsulation. */
219 if (!expression_allocate (expr
, MDL
)) {
220 log_error ("No memory for encapsulation expression node.");
224 (*expr
) -> op
= expr_encapsulate
;
225 data_string_copy (&(*expr
) -> data
.encapsulate
, name
, MDL
);
229 int make_substring (new, expr
, offset
, length
)
230 struct expression
**new;
231 struct expression
*expr
;
232 struct expression
*offset
;
233 struct expression
*length
;
235 /* Allocate an expression node to compute the substring. */
236 if (!expression_allocate (new, MDL
)) {
237 log_error ("no memory for substring expression.");
240 (*new) -> op
= expr_substring
;
241 expression_reference (&(*new) -> data
.substring
.expr
, expr
, MDL
);
242 expression_reference (&(*new) -> data
.substring
.offset
, offset
, MDL
);
243 expression_reference (&(*new) -> data
.substring
.len
, length
, MDL
);
247 int make_limit (new, expr
, limit
)
248 struct expression
**new;
249 struct expression
*expr
;
252 struct expression
*rv
;
254 /* Allocate a node to enforce a limit on evaluation. */
255 if (!expression_allocate (new, MDL
))
256 log_error ("no memory for limit expression");
257 (*new) -> op
= expr_substring
;
258 expression_reference (&(*new) -> data
.substring
.expr
, expr
, MDL
);
260 /* Offset is a constant 0. */
261 if (!expression_allocate (&(*new) -> data
.substring
.offset
, MDL
)) {
262 log_error ("no memory for limit offset expression");
263 expression_dereference (new, MDL
);
266 (*new) -> data
.substring
.offset
-> op
= expr_const_int
;
267 (*new) -> data
.substring
.offset
-> data
.const_int
= 0;
269 /* Length is a constant: the specified limit. */
270 if (!expression_allocate (&(*new) -> data
.substring
.len
, MDL
)) {
271 log_error ("no memory for limit length expression");
272 expression_dereference (new, MDL
);
275 (*new) -> data
.substring
.len
-> op
= expr_const_int
;
276 (*new) -> data
.substring
.len
-> data
.const_int
= limit
;
281 int option_cache (struct option_cache
**oc
, struct data_string
*dp
,
282 struct expression
*expr
, struct option
*option
,
283 const char *file
, int line
)
285 if (!option_cache_allocate (oc
, file
, line
))
288 data_string_copy (&(*oc
) -> data
, dp
, file
, line
);
290 expression_reference (&(*oc
) -> expression
, expr
, file
, line
);
291 (*oc
) -> option
= option
;
295 int make_let (result
, name
)
296 struct executable_statement
**result
;
299 if (!(executable_statement_allocate (result
, MDL
)))
302 (*result
) -> op
= let_statement
;
303 (*result
) -> data
.let
.name
= dmalloc (strlen (name
) + 1, MDL
);
304 if (!(*result
) -> data
.let
.name
) {
305 executable_statement_dereference (result
, MDL
);
308 strcpy ((*result
) -> data
.let
.name
, name
);
312 static int do_host_lookup (result
, dns
)
313 struct data_string
*result
;
314 struct dns_host_entry
*dns
;
321 log_debug ("time: now = %d dns = %d diff = %d",
322 cur_time
, dns
-> timeout
, cur_time
- dns
-> timeout
);
325 /* If the record hasn't timed out, just copy the data and return. */
326 if (cur_time
<= dns
-> timeout
) {
328 log_debug ("easy copy: %d %s",
331 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
))
334 data_string_copy (result
, &dns
-> data
, MDL
);
338 log_debug ("Looking up %s", dns
-> hostname
);
341 /* Otherwise, look it up... */
342 h
= gethostbyname (dns
-> hostname
);
348 log_error ("%s: host unknown.", dns
-> hostname
);
352 log_error ("%s: temporary name server failure",
356 log_error ("%s: name server failed", dns
-> hostname
);
359 log_error ("%s: no A record associated with address",
362 #endif /* !NO_H_ERRNO */
364 /* Okay to try again after a minute. */
365 dns
-> timeout
= cur_time
+ 60;
366 data_string_forget (&dns
-> data
, MDL
);
371 log_debug ("Lookup succeeded; first address is %s",
372 inet_ntoa (h
-> h_addr_list
[0]));
375 /* Count the number of addresses we got... */
376 for (count
= 0; h
-> h_addr_list
[count
]; count
++)
379 /* Dereference the old data, if any. */
380 data_string_forget (&dns
-> data
, MDL
);
382 /* Do we need to allocate more memory? */
383 new_len
= count
* h
-> h_length
;
384 if (!buffer_allocate (&dns
-> data
.buffer
, new_len
, MDL
))
386 log_error ("No memory for %s.", dns
-> hostname
);
390 dns
-> data
.data
= &dns
-> data
.buffer
-> data
[0];
391 dns
-> data
.len
= new_len
;
392 dns
-> data
.terminated
= 0;
394 /* Addresses are conveniently stored one to the buffer, so we
395 have to copy them out one at a time... :'( */
396 for (i
= 0; i
< count
; i
++) {
397 memcpy (&dns
-> data
.buffer
-> data
[h
-> h_length
* i
],
398 h
-> h_addr_list
[i
], (unsigned)(h
-> h_length
));
401 log_debug ("dns -> data: %x h -> h_addr_list [0]: %x",
402 *(int *)(dns
-> buffer
), h
-> h_addr_list
[0]);
405 /* XXX Set the timeout for an hour from now.
406 XXX This should really use the time on the DNS reply. */
407 dns
-> timeout
= cur_time
+ 3600;
410 log_debug ("hard copy: %d %s", dns
-> data
.len
,
412 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
)) : 0));
414 data_string_copy (result
, &dns
-> data
, MDL
);
418 int evaluate_expression (result
, packet
, lease
, client_state
,
419 in_options
, cfg_options
, scope
, expr
, file
, line
)
420 struct binding_value
**result
;
421 struct packet
*packet
;
423 struct client_state
*client_state
;
424 struct option_state
*in_options
;
425 struct option_state
*cfg_options
;
426 struct binding_scope
**scope
;
427 struct expression
*expr
;
431 struct binding_value
*bv
;
433 struct binding
*binding
;
435 bv
= (struct binding_value
*)0;
437 if (expr
-> op
== expr_variable_reference
) {
438 if (!scope
|| !*scope
)
441 binding
= find_binding (*scope
, expr
-> data
.variable
);
443 if (binding
&& binding
-> value
) {
445 binding_value_reference (result
,
451 } else if (expr
-> op
== expr_funcall
) {
452 struct string_list
*s
;
453 struct expression
*arg
;
454 struct binding_scope
*ns
;
457 if (!scope
|| !*scope
) {
458 log_error ("%s: no such function.",
459 expr
-> data
.funcall
.name
);
463 binding
= find_binding (*scope
, expr
-> data
.funcall
.name
);
465 if (!binding
|| !binding
-> value
) {
466 log_error ("%s: no such function.",
467 expr
-> data
.funcall
.name
);
470 if (binding
-> value
-> type
!= binding_function
) {
471 log_error ("%s: not a function.",
472 expr
-> data
.funcall
.name
);
476 /* Create a new binding scope in which to define
477 the arguments to the function. */
478 ns
= (struct binding_scope
*)0;
479 if (!binding_scope_allocate (&ns
, MDL
)) {
480 log_error ("%s: can't allocate argument scope.",
481 expr
-> data
.funcall
.name
);
485 arg
= expr
-> data
.funcall
.arglist
;
486 s
= binding
-> value
-> value
.fundef
-> args
;
488 nb
= dmalloc (sizeof *nb
, MDL
);
491 binding_scope_dereference (&ns
, MDL
);
494 memset (nb
, 0, sizeof *nb
);
495 nb
-> name
= dmalloc (strlen (s
-> string
) + 1,
498 strcpy (nb
-> name
, s
-> string
);
501 nb
= (struct binding
*)0;
505 evaluate_expression (&nb
-> value
, packet
, lease
,
507 in_options
, cfg_options
, scope
,
508 arg
-> data
.arg
.val
, file
, line
);
509 nb
-> next
= ns
-> bindings
;
511 arg
= arg
-> data
.arg
.next
;
515 log_error ("%s: too many arguments.",
516 expr
-> data
.funcall
.name
);
517 binding_scope_dereference (&ns
, MDL
);
521 log_error ("%s: too few arguments.",
522 expr
-> data
.funcall
.name
);
523 binding_scope_dereference (&ns
, MDL
);
528 binding_scope_reference (&ns
-> outer
, *scope
, MDL
);
530 status
= (execute_statements
532 lease
, client_state
, in_options
, cfg_options
, &ns
,
533 binding
-> value
-> value
.fundef
-> statements
));
534 binding_scope_dereference (&ns
, MDL
);
538 } else if (is_boolean_expression (expr
)) {
539 if (!binding_value_allocate (&bv
, MDL
))
541 bv
-> type
= binding_boolean
;
542 status
= (evaluate_boolean_expression
543 (&bv
-> value
.boolean
, packet
, lease
, client_state
,
544 in_options
, cfg_options
, scope
, expr
));
545 } else if (is_numeric_expression (expr
)) {
546 if (!binding_value_allocate (&bv
, MDL
))
548 bv
-> type
= binding_numeric
;
549 status
= (evaluate_numeric_expression
550 (&bv
-> value
.intval
, packet
, lease
, client_state
,
551 in_options
, cfg_options
, scope
, expr
));
552 } else if (is_data_expression (expr
)) {
553 if (!binding_value_allocate (&bv
, MDL
))
555 bv
-> type
= binding_data
;
556 status
= (evaluate_data_expression
557 (&bv
-> value
.data
, packet
, lease
, client_state
,
558 in_options
, cfg_options
, scope
, expr
, MDL
));
559 } else if (is_dns_expression (expr
)) {
560 #if defined (NSUPDATE)
561 if (!binding_value_allocate (&bv
, MDL
))
563 bv
-> type
= binding_dns
;
564 status
= (evaluate_dns_expression
565 (&bv
-> value
.dns
, packet
, lease
, client_state
,
566 in_options
, cfg_options
, scope
, expr
));
569 log_error ("%s: invalid expression type: %d",
570 "evaluate_expression", expr
-> op
);
573 if (result
&& status
)
574 binding_value_reference (result
, bv
, file
, line
);
575 binding_value_dereference (&bv
, MDL
);
580 int binding_value_dereference (struct binding_value
**v
,
581 const char *file
, int line
)
583 struct binding_value
*bv
= *v
;
585 *v
= (struct binding_value
*)0;
587 /* Decrement the reference count. If it's nonzero, we're
590 rc_register (file
, line
, v
, bv
, bv
-> refcnt
, 1, RC_MISC
);
591 if (bv
-> refcnt
> 0)
593 if (bv
-> refcnt
< 0) {
594 log_error ("%s(%d): negative refcnt!", file
, line
);
595 #if defined (DEBUG_RC_HISTORY)
596 dump_rc_history (bv
);
598 #if defined (POINTER_DEBUG)
605 switch (bv
-> type
) {
606 case binding_boolean
:
607 case binding_numeric
:
610 if (bv
-> value
.data
.buffer
)
611 data_string_forget (&bv
-> value
.data
, file
, line
);
614 #if defined (NSUPDATE)
615 if (bv
-> value
.dns
) {
616 if (bv
-> value
.dns
-> r_data
) {
617 dfree (bv
-> value
.dns
-> r_data_ephem
, MDL
);
618 bv
-> value
.dns
-> r_data
= (unsigned char *)0;
619 bv
-> value
.dns
-> r_data_ephem
=
622 minires_freeupdrec (bv
-> value
.dns
);
627 log_error ("%s(%d): invalid binding type: %d",
628 file
, line
, bv
-> type
);
631 dfree (bv
, file
, line
);
635 #if defined (NSUPDATE)
636 int evaluate_dns_expression (result
, packet
, lease
, client_state
, in_options
,
637 cfg_options
, scope
, expr
)
639 struct packet
*packet
;
641 struct client_state
*client_state
;
642 struct option_state
*in_options
;
643 struct option_state
*cfg_options
;
644 struct binding_scope
**scope
;
645 struct expression
*expr
;
648 unsigned long ttl
= 0;
650 struct data_string name
, data
;
653 if (!result
|| *result
) {
654 log_error ("evaluate_dns_expression called with non-null %s",
656 #if defined (POINTER_DEBUG)
663 switch (expr
-> op
) {
664 #if defined (NSUPDATE)
666 r0
= evaluate_numeric_expression (&ttl
, packet
, lease
,
668 in_options
, cfg_options
,
670 expr
-> data
.ns_add
.ttl
);
677 case expr_ns_not_exists
:
680 memset (&name
, 0, sizeof name
);
681 r1
= evaluate_data_expression (&name
, packet
, lease
,
683 in_options
, cfg_options
, scope
,
684 expr
-> data
.ns_add
.rrname
,
687 /* The result of the evaluation may or may not
688 be NUL-terminated, but we need it
689 terminated for sure, so we have to allocate
690 a buffer and terminate it. */
691 tname
= dmalloc (name
.len
+ 1, MDL
);
695 data_string_forget (&name
, MDL
);
697 memcpy (tname
, name
.data
, name
.len
);
698 tname
[name
.len
] = 0;
699 memset (&data
, 0, sizeof data
);
700 r2
= evaluate_data_expression
701 (&data
, packet
, lease
, client_state
,
702 in_options
, cfg_options
, scope
,
703 expr
-> data
.ns_add
.rrdata
, MDL
);
709 if (r0
&& r1
&& (r2
|| expr
-> op
!= expr_ns_add
)) {
710 *result
= minires_mkupdrec (((expr
-> op
== expr_ns_add
||
711 expr
-> op
== expr_ns_delete
)
712 ? S_UPDATE
: S_PREREQ
),
714 expr
-> data
.ns_add
.rrclass
,
715 expr
-> data
.ns_add
.rrtype
,
720 data_string_forget (&data
, MDL
);
725 /* As a special case, if we get exactly
726 four bytes of data, it's an IP address
727 represented as a 32-bit quantity, which
728 is actually what we *should* be getting
729 here. Because res_mkupdrec is currently
730 broken and expects a dotted quad, convert
731 it. This should be fixed when the new
732 resolver is merged. */
734 (*result
) -> r_data_ephem
=
736 if (!(*result
) -> r_data_ephem
)
738 (*result
) -> r_data
=
739 (*result
) -> r_data_ephem
;
740 /*%Audit% 16 bytes max. %2004.06.17,Safe%*/
741 sprintf ((char *)(*result
) -> r_data_ephem
,
743 data
.data
[0] & 0xff,
744 data
.data
[1] & 0xff,
745 data
.data
[2] & 0xff,
746 data
.data
[3] & 0xff);
747 (*result
) -> r_size
=
748 strlen ((const char *)
749 (*result
) -> r_data
);
751 (*result
) -> r_size
= data
.len
;
752 (*result
) -> r_data_ephem
=
753 dmalloc (data
.len
, MDL
);
754 if (!(*result
) -> r_data_ephem
) {
755 dpngood
: /* double plus ungood. */
756 minires_freeupdrec (*result
);
760 (*result
) -> r_data
=
761 (*result
) -> r_data_ephem
;
762 memcpy ((*result
) -> r_data_ephem
,
763 data
.data
, data
.len
);
766 (*result
) -> r_data
= 0;
767 (*result
) -> r_size
= 0;
769 switch (expr
-> op
) {
771 (*result
) -> r_opcode
= ADD
;
774 (*result
) -> r_opcode
= DELETE
;
777 (*result
) -> r_opcode
= YXRRSET
;
779 case expr_ns_not_exists
:
780 (*result
) -> r_opcode
= NXRRSET
;
783 /* Can't happen, but satisfy gcc. */
790 data_string_forget (&name
, MDL
);
794 data_string_forget (&data
, MDL
);
795 /* One flaw in the thinking here: an IP address and an
796 ASCII string both look like data expressions, but
797 for A records, we want an ASCII string, not a
798 binary IP address. Do I need to turn binary IP
799 addresses into a seperate type? */
801 (r2
|| expr
-> op
!= expr_ns_add
) && *result
);
807 case expr_ns_not_exists
:
811 log_error ("%s: dns values for functions not supported.",
812 expr
-> data
.funcall
.name
);
815 case expr_variable_reference
:
816 log_error ("%s: dns values for variables not supported.",
817 expr
-> data
.variable
);
830 case expr_variable_exists
:
831 log_error ("Boolean opcode in evaluate_dns_expression: %d",
840 case expr_const_data
:
843 case expr_encapsulate
:
844 case expr_host_lookup
:
845 case expr_encode_int8
:
846 case expr_encode_int16
:
847 case expr_encode_int32
:
848 case expr_binary_to_ascii
:
852 case expr_pick_first_value
:
853 case expr_host_decl_name
:
854 case expr_config_option
:
855 case expr_leased_address
:
857 log_error ("Data opcode in evaluate_dns_expression: %d",
861 case expr_extract_int8
:
862 case expr_extract_int16
:
863 case expr_extract_int32
:
865 case expr_lease_time
:
866 case expr_dns_transaction
:
872 case expr_binary_and
:
874 case expr_binary_xor
:
875 case expr_client_state
:
876 log_error ("Numeric opcode in evaluate_dns_expression: %d",
881 log_error ("Function opcode in evaluate_dns_expression: %d",
889 log_error ("Bogus opcode in evaluate_dns_expression: %d",
893 #endif /* defined (NSUPDATE) */
895 int evaluate_boolean_expression (result
, packet
, lease
, client_state
,
896 in_options
, cfg_options
, scope
, expr
)
898 struct packet
*packet
;
900 struct client_state
*client_state
;
901 struct option_state
*in_options
;
902 struct option_state
*cfg_options
;
903 struct binding_scope
**scope
;
904 struct expression
*expr
;
906 struct data_string left
, right
;
907 struct data_string rrtype
, rrname
, rrdata
;
909 int srrtype
, srrname
, srrdata
, sttl
;
912 struct binding
*binding
;
913 struct binding_value
*bv
, *obv
;
915 switch (expr
-> op
) {
917 *result
= check_collection (packet
, lease
,
919 #if defined (DEBUG_EXPRESSIONS)
920 log_debug ("bool: check (%s) returns %s",
921 expr
-> data
.check
-> name
,
922 *result
? "true" : "false");
928 bv
= obv
= (struct binding_value
*)0;
929 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
930 in_options
, cfg_options
, scope
,
931 expr
-> data
.equal
[0], MDL
);
932 sright
= evaluate_expression (&obv
, packet
, lease
,
933 client_state
, in_options
,
935 expr
-> data
.equal
[1], MDL
);
936 if (sleft
&& sright
) {
937 if (bv
-> type
!= obv
-> type
)
938 *result
= expr
-> op
== expr_not_equal
;
940 switch (obv
-> type
) {
941 case binding_boolean
:
942 if (bv
-> value
.boolean
== obv
-> value
.boolean
)
943 *result
= expr
-> op
== expr_equal
;
945 *result
= expr
-> op
== expr_not_equal
;
949 if ((bv
-> value
.data
.len
==
950 obv
-> value
.data
.len
) &&
951 !memcmp (bv
-> value
.data
.data
,
952 obv
-> value
.data
.data
,
953 obv
-> value
.data
.len
))
954 *result
= expr
-> op
== expr_equal
;
956 *result
= expr
-> op
== expr_not_equal
;
959 case binding_numeric
:
960 if (bv
-> value
.intval
== obv
-> value
.intval
)
961 *result
= expr
-> op
== expr_equal
;
963 *result
= expr
-> op
== expr_not_equal
;
967 #if defined (NSUPDATE)
968 /* XXX This should be a comparison for equal
969 XXX values, not for identity. */
970 if (bv
-> value
.dns
== obv
-> value
.dns
)
971 *result
= expr
-> op
== expr_equal
;
973 *result
= expr
-> op
== expr_not_equal
;
975 *result
= expr
-> op
== expr_not_equal
;
979 case binding_function
:
980 if (bv
-> value
.fundef
== obv
-> value
.fundef
)
981 *result
= expr
-> op
== expr_equal
;
983 *result
= expr
-> op
== expr_not_equal
;
986 *result
= expr
-> op
== expr_not_equal
;
990 } else if (!sleft
&& !sright
)
991 *result
= expr
-> op
== expr_equal
;
993 *result
= expr
-> op
== expr_not_equal
;
995 #if defined (DEBUG_EXPRESSIONS)
996 log_debug ("bool: %sequal = %s",
997 expr
-> op
== expr_not_equal
? "not" : "",
998 (*result
? "true" : "false"));
1001 binding_value_dereference (&bv
, MDL
);
1003 binding_value_dereference (&obv
, MDL
);
1007 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1009 in_options
, cfg_options
,
1011 expr
-> data
.and [0]);
1013 sright
= evaluate_boolean_expression
1014 (&bright
, packet
, lease
, client_state
,
1015 in_options
, cfg_options
,
1016 scope
, expr
-> data
.and [1]);
1018 sright
= bright
= 0;
1020 #if defined (DEBUG_EXPRESSIONS)
1021 log_debug ("bool: and (%s, %s) = %s",
1022 sleft
? (bleft
? "true" : "false") : "NULL",
1023 sright
? (bright
? "true" : "false") : "NULL",
1025 ? (bleft
&& bright
? "true" : "false") : "NULL"));
1027 if (sleft
&& sright
) {
1028 *result
= bleft
&& bright
;
1035 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1037 in_options
, cfg_options
,
1039 expr
-> data
.or [0]);
1040 if (!sleft
|| !bleft
)
1041 sright
= evaluate_boolean_expression
1042 (&bright
, packet
, lease
, client_state
,
1043 in_options
, cfg_options
,
1044 scope
, expr
-> data
.or [1]);
1047 #if defined (DEBUG_EXPRESSIONS)
1048 log_debug ("bool: or (%s, %s) = %s",
1049 sleft
? (bleft
? "true" : "false") : "NULL",
1050 sright
? (bright
? "true" : "false") : "NULL",
1052 ? (bleft
|| bright
? "true" : "false") : "NULL"));
1054 if (sleft
|| sright
) {
1055 *result
= bleft
|| bright
;
1061 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1063 in_options
, cfg_options
,
1066 #if defined (DEBUG_EXPRESSIONS)
1067 log_debug ("bool: not (%s) = %s",
1068 sleft
? (bleft
? "true" : "false") : "NULL",
1070 ? (!bleft
? "true" : "false") : "NULL"));
1080 memset (&left
, 0, sizeof left
);
1082 !get_option (&left
, expr
-> data
.exists
-> universe
,
1083 packet
, lease
, client_state
,
1084 in_options
, cfg_options
, in_options
,
1085 scope
, expr
-> data
.exists
-> code
, MDL
))
1089 data_string_forget (&left
, MDL
);
1091 #if defined (DEBUG_EXPRESSIONS)
1092 log_debug ("bool: exists %s.%s = %s",
1093 expr
-> data
.option
-> universe
-> name
,
1094 expr
-> data
.option
-> name
,
1095 *result
? "true" : "false");
1101 #if defined (DEBUG_EXPRESSIONS)
1102 log_debug ("bool: known = NULL");
1106 #if defined (DEBUG_EXPRESSIONS)
1107 log_debug ("bool: known = %s",
1108 packet
-> known
? "true" : "false");
1110 *result
= packet
-> known
;
1114 if (!lease
|| !(lease
-> flags
& STATIC_LEASE
)) {
1115 #if defined (DEBUG_EXPRESSIONS)
1116 log_debug ("bool: static = false (%s %s %s %d)",
1118 (lease
&& (lease
-> flags
& STATIC_LEASE
)
1120 piaddr (lease
-> ip_addr
),
1121 lease
? lease
-> flags
: 0);
1126 #if defined (DEBUG_EXPRESSIONS)
1127 log_debug ("bool: static = true");
1132 case expr_variable_exists
:
1133 if (scope
&& *scope
) {
1134 binding
= find_binding (*scope
, expr
-> data
.variable
);
1137 if (binding
-> value
)
1145 #if defined (DEBUG_EXPRESSIONS)
1146 log_debug ("boolean: %s? = %s", expr
-> data
.variable
,
1147 *result
? "true" : "false");
1151 case expr_variable_reference
:
1152 if (scope
&& *scope
) {
1153 binding
= find_binding (*scope
, expr
-> data
.variable
);
1155 if (binding
&& binding
-> value
) {
1156 if (binding
-> value
-> type
==
1158 *result
= binding
-> value
-> value
.boolean
;
1161 log_error ("binding type %d in %s.",
1162 binding
-> value
-> type
,
1163 "evaluate_boolean_expression");
1170 #if defined (DEBUG_EXPRESSIONS)
1171 log_debug ("boolean: %s = %s", expr
-> data
.variable
,
1172 sleft
? (*result
? "true" : "false") : "NULL");
1177 bv
= (struct binding_value
*)0;
1178 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1179 in_options
, cfg_options
,
1182 if (bv
-> type
!= binding_boolean
)
1183 log_error ("%s() returned type %d in %s.",
1184 expr
-> data
.funcall
.name
,
1186 "evaluate_boolean_expression");
1188 *result
= bv
-> value
.boolean
;
1189 binding_value_dereference (&bv
, MDL
);
1191 #if defined (DEBUG_EXPRESSIONS)
1192 log_debug ("boolean: %s() = %s", expr
-> data
.funcall
.name
,
1193 sleft
? (*result
? "true" : "false") : "NULL");
1199 case expr_substring
:
1203 case expr_const_data
:
1206 case expr_encapsulate
:
1207 case expr_host_lookup
:
1208 case expr_encode_int8
:
1209 case expr_encode_int16
:
1210 case expr_encode_int32
:
1211 case expr_binary_to_ascii
:
1213 case expr_pick_first_value
:
1214 case expr_host_decl_name
:
1215 case expr_config_option
:
1216 case expr_leased_address
:
1220 log_error ("Data opcode in evaluate_boolean_expression: %d",
1224 case expr_extract_int8
:
1225 case expr_extract_int16
:
1226 case expr_extract_int32
:
1227 case expr_const_int
:
1228 case expr_lease_time
:
1229 case expr_dns_transaction
:
1234 case expr_remainder
:
1235 case expr_binary_and
:
1236 case expr_binary_or
:
1237 case expr_binary_xor
:
1238 case expr_client_state
:
1239 log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1244 case expr_ns_delete
:
1245 case expr_ns_exists
:
1246 case expr_ns_not_exists
:
1247 log_error ("dns opcode in evaluate_boolean_expression: %d",
1252 log_error ("function definition in evaluate_boolean_expr");
1259 log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1264 int evaluate_data_expression (result
, packet
, lease
, client_state
,
1265 in_options
, cfg_options
, scope
, expr
, file
, line
)
1266 struct data_string
*result
;
1267 struct packet
*packet
;
1268 struct lease
*lease
;
1269 struct client_state
*client_state
;
1270 struct option_state
*in_options
;
1271 struct option_state
*cfg_options
;
1272 struct binding_scope
**scope
;
1273 struct expression
*expr
;
1277 struct data_string data
, other
;
1278 unsigned long offset
, len
, i
;
1281 struct binding
*binding
;
1283 struct binding_value
*bv
;
1285 switch (expr
-> op
) {
1286 /* Extract N bytes starting at byte M of a data string. */
1287 case expr_substring
:
1288 memset (&data
, 0, sizeof data
);
1289 s0
= evaluate_data_expression (&data
, packet
, lease
,
1291 in_options
, cfg_options
, scope
,
1292 expr
-> data
.substring
.expr
,
1295 /* Evaluate the offset and length. */
1296 s1
= evaluate_numeric_expression
1297 (&offset
, packet
, lease
, client_state
, in_options
,
1298 cfg_options
, scope
, expr
-> data
.substring
.offset
);
1299 s2
= evaluate_numeric_expression (&len
, packet
, lease
,
1301 in_options
, cfg_options
,
1303 expr
-> data
.substring
.len
);
1305 if (s0
&& s1
&& s2
) {
1306 /* If the offset is after end of the string,
1307 return an empty string. Otherwise, do the
1308 adjustments and return what's left. */
1309 if (data
.len
> offset
) {
1310 data_string_copy (result
, &data
, file
, line
);
1311 result
-> len
-= offset
;
1312 if (result
-> len
> len
) {
1313 result
-> len
= len
;
1314 result
-> terminated
= 0;
1316 result
-> data
+= offset
;
1322 #if defined (DEBUG_EXPRESSIONS)
1323 log_debug ("data: substring (%s, %s, %s) = %s",
1324 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1325 s1
? print_dec_1 (offset
) : "NULL",
1326 s2
? print_dec_2 (len
) : "NULL",
1327 (s3
? print_hex_2 (result
-> len
, result
-> data
, 30)
1331 data_string_forget (&data
, MDL
);
1337 /* Extract the last N bytes of a data string. */
1339 memset (&data
, 0, sizeof data
);
1340 s0
= evaluate_data_expression (&data
, packet
, lease
,
1342 in_options
, cfg_options
, scope
,
1343 expr
-> data
.suffix
.expr
, MDL
);
1344 /* Evaluate the length. */
1345 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1347 in_options
, cfg_options
,
1349 expr
-> data
.suffix
.len
);
1351 data_string_copy (result
, &data
, file
, line
);
1353 /* If we are returning the last N bytes of a
1354 string whose length is <= N, just return
1355 the string - otherwise, compute a new
1356 starting address and decrease the
1358 if (data
.len
> len
) {
1359 result
-> data
+= data
.len
- len
;
1360 result
-> len
= len
;
1362 data_string_forget (&data
, MDL
);
1365 #if defined (DEBUG_EXPRESSIONS)
1366 log_debug ("data: suffix (%s, %s) = %s",
1367 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1368 s1
? print_dec_1 (len
) : "NULL",
1370 ? print_hex_2 (result
-> len
, result
-> data
, 30)
1375 /* Extract an option. */
1378 s0
= get_option (result
,
1379 expr
-> data
.option
-> universe
,
1380 packet
, lease
, client_state
,
1381 in_options
, cfg_options
, in_options
,
1382 scope
, expr
-> data
.option
-> code
,
1387 #if defined (DEBUG_EXPRESSIONS)
1388 log_debug ("data: option %s.%s = %s",
1389 expr
-> data
.option
-> universe
-> name
,
1390 expr
-> data
.option
-> name
,
1391 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1396 case expr_config_option
:
1398 s0
= get_option (result
,
1399 expr
-> data
.option
-> universe
,
1400 packet
, lease
, client_state
,
1401 in_options
, cfg_options
, cfg_options
,
1402 scope
, expr
-> data
.option
-> code
,
1407 #if defined (DEBUG_EXPRESSIONS)
1408 log_debug ("data: config-option %s.%s = %s",
1409 expr
-> data
.option
-> universe
-> name
,
1410 expr
-> data
.option
-> name
,
1411 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1416 /* Combine the hardware type and address. */
1418 /* On the client, hardware is our hardware. */
1420 memset (result
, 0, sizeof *result
);
1422 client_state
-> interface
-> hw_address
.hbuf
;
1424 client_state
-> interface
-> hw_address
.hlen
;
1425 #if defined (DEBUG_EXPRESSIONS)
1426 log_debug ("data: hardware = %s",
1427 print_hex_1 (result
-> len
,
1428 result
-> data
, 60));
1433 /* The server cares about the client's hardware address,
1434 so only in the case where we are examining a packet can
1435 we return anything. */
1436 if (!packet
|| !packet
-> raw
) {
1437 log_error ("data: hardware: raw packet not available");
1440 if (packet
-> raw
-> hlen
> sizeof packet
-> raw
-> chaddr
) {
1441 log_error ("data: hardware: invalid hlen (%d)\n",
1442 packet
-> raw
-> hlen
);
1445 result
-> len
= packet
-> raw
-> hlen
+ 1;
1446 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1448 result
-> data
= &result
-> buffer
-> data
[0];
1449 result
-> buffer
-> data
[0] = packet
-> raw
-> htype
;
1450 memcpy (&result
-> buffer
-> data
[1],
1451 packet
-> raw
-> chaddr
,
1452 packet
-> raw
-> hlen
);
1453 result
-> terminated
= 0;
1455 log_error ("data: hardware: no memory for buffer.");
1458 #if defined (DEBUG_EXPRESSIONS)
1459 log_debug ("data: hardware = %s",
1460 print_hex_1 (result
-> len
, result
-> data
, 60));
1464 /* Extract part of the raw packet. */
1466 if (!packet
|| !packet
-> raw
) {
1467 log_error ("data: packet: raw packet not available");
1471 s0
= evaluate_numeric_expression (&offset
, packet
, lease
,
1473 in_options
, cfg_options
,
1475 expr
-> data
.packet
.offset
);
1476 s1
= evaluate_numeric_expression (&len
,
1477 packet
, lease
, client_state
,
1478 in_options
, cfg_options
,
1480 expr
-> data
.packet
.len
);
1481 if (s0
&& s1
&& offset
< packet
-> packet_length
) {
1482 if (offset
+ len
> packet
-> packet_length
)
1484 packet
-> packet_length
- offset
;
1486 result
-> len
= len
;
1487 if (buffer_allocate (&result
-> buffer
,
1488 result
-> len
, file
, line
)) {
1489 result
-> data
= &result
-> buffer
-> data
[0];
1490 memcpy (result
-> buffer
-> data
,
1491 (((unsigned char *)(packet
-> raw
))
1492 + offset
), result
-> len
);
1493 result
-> terminated
= 0;
1495 log_error ("data: packet: no buffer memory.");
1501 #if defined (DEBUG_EXPRESSIONS)
1502 log_debug ("data: packet (%ld, %ld) = %s",
1504 s2
? print_hex_1 (result
-> len
,
1505 result
-> data
, 60) : NULL
);
1509 /* The encapsulation of all defined options in an
1511 case expr_encapsulate
:
1513 s0
= option_space_encapsulate
1514 (result
, packet
, lease
, client_state
,
1515 in_options
, cfg_options
, scope
,
1516 &expr
-> data
.encapsulate
);
1520 #if defined (DEBUG_EXPRESSIONS)
1521 log_debug ("data: encapsulate (%s) = %s",
1522 expr
-> data
.encapsulate
.data
,
1523 s0
? print_hex_1 (result
-> len
,
1524 result
-> data
, 60) : "NULL");
1528 /* Some constant data... */
1529 case expr_const_data
:
1530 #if defined (DEBUG_EXPRESSIONS)
1531 log_debug ("data: const = %s",
1532 print_hex_1 (expr
-> data
.const_data
.len
,
1533 expr
-> data
.const_data
.data
, 60));
1535 data_string_copy (result
,
1536 &expr
-> data
.const_data
, file
, line
);
1539 /* Hostname lookup... */
1540 case expr_host_lookup
:
1541 s0
= do_host_lookup (result
, expr
-> data
.host_lookup
);
1542 #if defined (DEBUG_EXPRESSIONS)
1543 log_debug ("data: DNS lookup (%s) = %s",
1544 expr
-> data
.host_lookup
-> hostname
,
1546 ? print_dotted_quads (result
-> len
, result
-> data
)
1551 /* Concatenation... */
1553 memset (&data
, 0, sizeof data
);
1554 s0
= evaluate_data_expression (&data
, packet
, lease
,
1556 in_options
, cfg_options
, scope
,
1557 expr
-> data
.concat
[0], MDL
);
1558 memset (&other
, 0, sizeof other
);
1559 s1
= evaluate_data_expression (&other
, packet
, lease
,
1561 in_options
, cfg_options
, scope
,
1562 expr
-> data
.concat
[1], MDL
);
1565 result
-> len
= data
.len
+ other
.len
;
1566 if (!buffer_allocate (&result
-> buffer
,
1567 (result
-> len
+ other
.terminated
),
1569 log_error ("data: concat: no memory");
1571 data_string_forget (&data
, MDL
);
1572 data_string_forget (&other
, MDL
);
1575 result
-> data
= &result
-> buffer
-> data
[0];
1576 memcpy (result
-> buffer
-> data
, data
.data
, data
.len
);
1577 memcpy (&result
-> buffer
-> data
[data
.len
],
1578 other
.data
, other
.len
+ other
.terminated
);
1582 data_string_forget (&data
, MDL
);
1584 data_string_forget (&other
, MDL
);
1585 #if defined (DEBUG_EXPRESSIONS)
1586 log_debug ("data: concat (%s, %s) = %s",
1587 s0
? print_hex_1 (data
.len
, data
.data
, 20) : "NULL",
1588 s1
? print_hex_2 (other
.len
, other
.data
, 20) : "NULL",
1590 ? print_hex_3 (result
-> len
, result
-> data
, 30)
1595 case expr_encode_int8
:
1596 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1598 in_options
, cfg_options
,
1600 expr
-> data
.encode_int
);
1603 if (!buffer_allocate (&result
-> buffer
,
1605 log_error ("data: encode_int8: no memory");
1609 result
-> data
= &result
-> buffer
-> data
[0];
1610 result
-> buffer
-> data
[0] = len
;
1615 #if defined (DEBUG_EXPRESSIONS)
1617 log_debug ("data: encode_int8 (NULL) = NULL");
1619 log_debug ("data: encode_int8 (%ld) = %s", len
,
1620 print_hex_2 (result
-> len
,
1621 result
-> data
, 20));
1626 case expr_encode_int16
:
1627 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1629 in_options
, cfg_options
,
1631 expr
-> data
.encode_int
);
1634 if (!buffer_allocate (&result
-> buffer
, 2,
1636 log_error ("data: encode_int16: no memory");
1640 result
-> data
= &result
-> buffer
-> data
[0];
1641 putUShort (result
-> buffer
-> data
, len
);
1646 #if defined (DEBUG_EXPRESSIONS)
1648 log_debug ("data: encode_int16 (NULL) = NULL");
1650 log_debug ("data: encode_int16 (%ld) = %s", len
,
1651 print_hex_2 (result
-> len
,
1652 result
-> data
, 20));
1656 case expr_encode_int32
:
1657 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1659 in_options
, cfg_options
,
1661 expr
-> data
.encode_int
);
1664 if (!buffer_allocate (&result
-> buffer
, 4,
1666 log_error ("data: encode_int32: no memory");
1670 result
-> data
= &result
-> buffer
-> data
[0];
1671 putULong (result
-> buffer
-> data
, len
);
1676 #if defined (DEBUG_EXPRESSIONS)
1678 log_debug ("data: encode_int32 (NULL) = NULL");
1680 log_debug ("data: encode_int32 (%ld) = %s", len
,
1681 print_hex_2 (result
-> len
,
1682 result
-> data
, 20));
1686 case expr_binary_to_ascii
:
1687 /* Evaluate the base (offset) and width (len): */
1688 s0
= evaluate_numeric_expression
1689 (&offset
, packet
, lease
, client_state
, in_options
,
1690 cfg_options
, scope
, expr
-> data
.b2a
.base
);
1691 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1693 in_options
, cfg_options
,
1695 expr
-> data
.b2a
.width
);
1697 /* Evaluate the seperator string. */
1698 memset (&data
, 0, sizeof data
);
1699 s2
= evaluate_data_expression (&data
, packet
, lease
,
1701 in_options
, cfg_options
, scope
,
1702 expr
-> data
.b2a
.seperator
,
1705 /* Evaluate the data to be converted. */
1706 memset (&other
, 0, sizeof other
);
1707 s3
= evaluate_data_expression (&other
, packet
, lease
,
1709 in_options
, cfg_options
, scope
,
1710 expr
-> data
.b2a
.buffer
, MDL
);
1712 if (s0
&& s1
&& s2
&& s3
) {
1715 if (len
!= 8 && len
!= 16 && len
!= 32) {
1716 log_info ("binary_to_ascii: %s %ld!",
1717 "invalid width", len
);
1723 /* The buffer must be a multiple of the number's
1725 if (other
.len
% len
) {
1726 log_info ("binary-to-ascii: %s %d %s %ld!",
1727 "length of buffer", other
.len
,
1728 "not a multiple of width", len
);
1733 /* Count the width of the output. */
1735 for (i
= 0; i
< other
.len
; i
+= len
) {
1738 if (other
.data
[i
] < 8)
1740 else if (other
.data
[i
] < 64)
1744 } else if (offset
== 10) {
1745 if (other
.data
[i
] < 10)
1747 else if (other
.data
[i
] < 100)
1751 } else if (offset
== 16) {
1752 if (other
.data
[i
] < 16)
1757 buflen
+= (converted_length
1761 buflen
+= (converted_length
1764 if (i
+ len
!= other
.len
)
1768 if (!buffer_allocate (&result
-> buffer
,
1769 buflen
+ 1, file
, line
)) {
1770 log_error ("data: binary-to-ascii: no memory");
1774 result
-> data
= &result
-> buffer
-> data
[0];
1775 result
-> len
= buflen
;
1776 result
-> terminated
= 1;
1779 for (i
= 0; i
< other
.len
; i
+= len
) {
1780 buflen
+= (binary_to_ascii
1781 (&result
-> buffer
-> data
[buflen
],
1782 &other
.data
[i
], offset
, len
));
1783 if (i
+ len
!= other
.len
) {
1785 buffer
-> data
[buflen
],
1786 data
.data
, data
.len
);
1790 /* NUL terminate. */
1791 result
-> buffer
-> data
[buflen
] = 0;
1797 #if defined (DEBUG_EXPRESSIONS)
1798 log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
1799 s0
? print_dec_1 (offset
) : "NULL",
1800 s1
? print_dec_2 (len
) : "NULL",
1801 s2
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1802 s3
? print_hex_2 (other
.len
, other
.data
, 30) : "NULL",
1803 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1807 data_string_forget (&data
, MDL
);
1809 data_string_forget (&other
, MDL
);
1815 /* Evaluate the width (len): */
1816 s0
= evaluate_numeric_expression
1817 (&len
, packet
, lease
, client_state
, in_options
,
1818 cfg_options
, scope
, expr
-> data
.reverse
.width
);
1820 /* Evaluate the data. */
1821 memset (&data
, 0, sizeof data
);
1822 s1
= evaluate_data_expression (&data
, packet
, lease
,
1824 in_options
, cfg_options
, scope
,
1825 expr
-> data
.reverse
.buffer
,
1832 /* The buffer must be a multiple of the number's
1834 if (data
.len
% len
) {
1835 log_info ("reverse: %s %d %s %ld!",
1836 "length of buffer", data
.len
,
1837 "not a multiple of width", len
);
1842 /* XXX reverse in place? I don't think we can. */
1843 if (!buffer_allocate (&result
-> buffer
,
1844 data
.len
, file
, line
)) {
1845 log_error ("data: reverse: no memory");
1849 result
-> data
= &result
-> buffer
-> data
[0];
1850 result
-> len
= data
.len
;
1851 result
-> terminated
= 0;
1853 for (i
= 0; i
< data
.len
; i
+= len
) {
1854 memcpy (&result
-> buffer
-> data
[i
],
1855 &data
.data
[data
.len
- i
- len
], len
);
1862 #if defined (DEBUG_EXPRESSIONS)
1863 log_debug ("data: reverse (%s, %s) = %s",
1864 s0
? print_dec_1 (len
) : "NULL",
1865 s1
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1866 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1870 data_string_forget (&data
, MDL
);
1875 case expr_leased_address
:
1877 log_error ("data: leased_address: not available");
1880 result
-> len
= lease
-> ip_addr
.len
;
1881 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1883 result
-> data
= &result
-> buffer
-> data
[0];
1884 memcpy (&result
-> buffer
-> data
[0],
1885 lease
-> ip_addr
.iabuf
, lease
-> ip_addr
.len
);
1886 result
-> terminated
= 0;
1888 log_error ("data: leased-address: no memory.");
1891 #if defined (DEBUG_EXPRESSIONS)
1892 log_debug ("data: leased-address = %s",
1893 print_hex_1 (result
-> len
, result
-> data
, 60));
1897 case expr_pick_first_value
:
1898 memset (&data
, 0, sizeof data
);
1899 if ((evaluate_data_expression
1901 lease
, client_state
, in_options
, cfg_options
,
1902 scope
, expr
-> data
.pick_first_value
.car
, MDL
))) {
1903 #if defined (DEBUG_EXPRESSIONS)
1904 log_debug ("data: pick_first_value (%s, xxx)",
1905 print_hex_1 (result
-> len
,
1906 result
-> data
, 40));
1911 if (expr
-> data
.pick_first_value
.cdr
&&
1912 (evaluate_data_expression
1914 lease
, client_state
, in_options
, cfg_options
,
1915 scope
, expr
-> data
.pick_first_value
.cdr
, MDL
))) {
1916 #if defined (DEBUG_EXPRESSIONS)
1917 log_debug ("data: pick_first_value (NULL, %s)",
1918 print_hex_1 (result
-> len
,
1919 result
-> data
, 40));
1924 #if defined (DEBUG_EXPRESSIONS)
1925 log_debug ("data: pick_first_value (NULL, NULL) = NULL");
1929 case expr_host_decl_name
:
1930 if (!lease
|| !lease
-> host
) {
1931 log_error ("data: host_decl_name: not available");
1934 result
-> len
= strlen (lease
-> host
-> name
);
1935 if (buffer_allocate (&result
-> buffer
,
1936 result
-> len
+ 1, file
, line
)) {
1937 result
-> data
= &result
-> buffer
-> data
[0];
1938 strcpy ((char *)&result
-> buffer
-> data
[0],
1939 lease
-> host
-> name
);
1940 result
-> terminated
= 1;
1942 log_error ("data: host-decl-name: no memory.");
1945 #if defined (DEBUG_EXPRESSIONS)
1946 log_debug ("data: host-decl-name = %s", lease
-> host
-> name
);
1951 #if defined (DEBUG_EXPRESSIONS)
1952 log_debug ("data: null = NULL");
1956 case expr_variable_reference
:
1957 if (scope
&& *scope
) {
1958 binding
= find_binding (*scope
, expr
-> data
.variable
);
1960 if (binding
&& binding
-> value
) {
1961 if (binding
-> value
-> type
== binding_data
) {
1962 data_string_copy (result
,
1963 &binding
-> value
-> value
.data
,
1966 } else if (binding
-> value
-> type
!= binding_data
) {
1967 log_error ("binding type %d in %s.",
1968 binding
-> value
-> type
,
1969 "evaluate_data_expression");
1977 #if defined (DEBUG_EXPRESSIONS)
1978 log_debug ("data: %s = %s", expr
-> data
.variable
,
1979 s0
? print_hex_1 (result
-> len
,
1980 result
-> data
, 50) : "NULL");
1985 bv
= (struct binding_value
*)0;
1986 s0
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1987 in_options
, cfg_options
,
1990 if (bv
-> type
!= binding_data
)
1991 log_error ("%s() returned type %d in %s.",
1992 expr
-> data
.funcall
.name
,
1994 "evaluate_data_expression");
1996 data_string_copy (result
, &bv
-> value
.data
,
1998 binding_value_dereference (&bv
, MDL
);
2000 #if defined (DEBUG_EXPRESSIONS)
2001 log_debug ("data: %s = %s", expr
-> data
.funcall
.name
,
2002 s0
? print_hex_1 (result
-> len
,
2003 result
-> data
, 50) : "NULL");
2007 /* Extract the filename. */
2009 if (packet
&& packet
-> raw
-> file
[0]) {
2011 memchr (packet
-> raw
-> file
, 0,
2012 sizeof packet
-> raw
-> file
);
2014 fn
= ((char *)packet
-> raw
-> file
+
2015 sizeof packet
-> raw
-> file
);
2016 result
-> len
= fn
- &(packet
-> raw
-> file
[0]);
2017 if (buffer_allocate (&result
-> buffer
,
2018 result
-> len
+ 1, file
, line
)) {
2019 result
-> data
= &result
-> buffer
-> data
[0];
2020 memcpy (&result
-> buffer
-> data
[0],
2021 packet
-> raw
-> file
,
2023 result
-> buffer
-> data
[result
-> len
] = 0;
2024 result
-> terminated
= 1;
2027 log_error ("data: filename: no memory.");
2033 #if defined (DEBUG_EXPRESSIONS)
2034 log_info ("data: filename = \"%s\"",
2035 s0
? (const char *)(result
-> data
) : "NULL");
2039 /* Extract the server name. */
2041 if (packet
&& packet
-> raw
-> sname
[0]) {
2043 memchr (packet
-> raw
-> sname
, 0,
2044 sizeof packet
-> raw
-> sname
);
2046 fn
= ((char *)packet
-> raw
-> sname
+
2047 sizeof packet
-> raw
-> sname
);
2048 result
-> len
= fn
- &packet
-> raw
-> sname
[0];
2049 if (buffer_allocate (&result
-> buffer
,
2050 result
-> len
+ 1, file
, line
)) {
2051 result
-> data
= &result
-> buffer
-> data
[0];
2052 memcpy (&result
-> buffer
-> data
[0],
2053 packet
-> raw
-> sname
,
2055 result
-> buffer
-> data
[result
-> len
] = 0;
2056 result
-> terminated
= 1;
2059 log_error ("data: sname: no memory.");
2065 #if defined (DEBUG_EXPRESSIONS)
2066 log_info ("data: sname = \"%s\"",
2067 s0
? (const char *)(result
-> data
) : "NULL");
2073 case expr_not_equal
:
2082 case expr_variable_exists
:
2083 log_error ("Boolean opcode in evaluate_data_expression: %d",
2087 case expr_extract_int8
:
2088 case expr_extract_int16
:
2089 case expr_extract_int32
:
2090 case expr_const_int
:
2091 case expr_lease_time
:
2092 case expr_dns_transaction
:
2097 case expr_remainder
:
2098 case expr_binary_and
:
2099 case expr_binary_or
:
2100 case expr_binary_xor
:
2101 case expr_client_state
:
2102 log_error ("Numeric opcode in evaluate_data_expression: %d",
2107 case expr_ns_delete
:
2108 case expr_ns_exists
:
2109 case expr_ns_not_exists
:
2110 log_error ("dns update opcode in evaluate_data_expression: %d",
2115 log_error ("function definition in evaluate_data_expression");
2122 log_error ("Bogus opcode in evaluate_data_expression: %d", expr
-> op
);
2126 int evaluate_numeric_expression (result
, packet
, lease
, client_state
,
2127 in_options
, cfg_options
, scope
, expr
)
2128 unsigned long *result
;
2129 struct packet
*packet
;
2130 struct lease
*lease
;
2131 struct client_state
*client_state
;
2132 struct option_state
*in_options
;
2133 struct option_state
*cfg_options
;
2134 struct binding_scope
**scope
;
2135 struct expression
*expr
;
2137 struct data_string data
;
2138 int status
, sleft
, sright
;
2139 #if defined (NSUPDATE)
2143 struct expression
*cur
, *next
;
2144 struct binding
*binding
;
2145 struct binding_value
*bv
;
2146 unsigned long ileft
, iright
;
2148 switch (expr
-> op
) {
2151 case expr_not_equal
:
2160 case expr_variable_exists
:
2161 log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2165 case expr_substring
:
2169 case expr_const_data
:
2172 case expr_encapsulate
:
2173 case expr_host_lookup
:
2174 case expr_encode_int8
:
2175 case expr_encode_int16
:
2176 case expr_encode_int32
:
2177 case expr_binary_to_ascii
:
2181 case expr_pick_first_value
:
2182 case expr_host_decl_name
:
2183 case expr_config_option
:
2184 case expr_leased_address
:
2186 log_error ("Data opcode in evaluate_numeric_expression: %d",
2190 case expr_extract_int8
:
2191 memset (&data
, 0, sizeof data
);
2192 status
= evaluate_data_expression
2193 (&data
, packet
, lease
, client_state
, in_options
,
2194 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
);
2196 *result
= data
.data
[0];
2197 #if defined (DEBUG_EXPRESSIONS)
2198 log_debug ("num: extract_int8 (%s) = %s",
2199 status
? print_hex_1 (data
.len
, data
.data
, 60) : "NULL",
2200 status
? print_dec_1 (*result
) : "NULL" );
2202 if (status
) data_string_forget (&data
, MDL
);
2205 case expr_extract_int16
:
2206 memset (&data
, 0, sizeof data
);
2207 status
= (evaluate_data_expression
2208 (&data
, packet
, lease
, client_state
, in_options
,
2209 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2210 if (status
&& data
.len
>= 2)
2211 *result
= getUShort (data
.data
);
2212 #if defined (DEBUG_EXPRESSIONS)
2213 log_debug ("num: extract_int16 (%s) = %ld",
2214 ((status
&& data
.len
>= 2) ?
2215 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2218 if (status
) data_string_forget (&data
, MDL
);
2219 return (status
&& data
.len
>= 2);
2221 case expr_extract_int32
:
2222 memset (&data
, 0, sizeof data
);
2223 status
= (evaluate_data_expression
2224 (&data
, packet
, lease
, client_state
, in_options
,
2225 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2226 if (status
&& data
.len
>= 4)
2227 *result
= getULong (data
.data
);
2228 #if defined (DEBUG_EXPRESSIONS)
2229 log_debug ("num: extract_int32 (%s) = %ld",
2230 ((status
&& data
.len
>= 4) ?
2231 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2234 if (status
) data_string_forget (&data
, MDL
);
2235 return (status
&& data
.len
>= 4);
2237 case expr_const_int
:
2238 *result
= expr
-> data
.const_int
;
2239 #if defined (DEBUG_EXPRESSIONS)
2240 log_debug ("number: CONSTANT = %ld", *result
);
2244 case expr_lease_time
:
2246 log_error ("data: leased_lease: not available");
2249 if (lease
-> ends
< cur_time
) {
2250 log_error ("%s %lu when it is now %lu",
2251 "data: lease_time: lease ends at",
2252 (long)(lease
-> ends
), (long)cur_time
);
2255 *result
= lease
-> ends
- cur_time
;
2256 #if defined (DEBUG_EXPRESSIONS)
2257 log_debug ("number: lease-time = (%lu - %lu) = %ld",
2263 case expr_dns_transaction
:
2264 #if !defined (NSUPDATE)
2267 if (!resolver_inited
) {
2268 minires_ninit (&resolver_state
);
2269 resolver_inited
= 1;
2270 resolver_state
.retrans
= 1;
2271 resolver_state
.retry
= 1;
2276 next
= cur
-> data
.dns_transaction
.cdr
;
2278 status
= (evaluate_dns_expression
2280 lease
, client_state
, in_options
, cfg_options
,
2281 scope
, cur
-> data
.dns_transaction
.car
));
2284 ISC_LIST_APPEND (uq
, nut
, r_link
);
2288 /* Do the update and record the error code, if there was
2289 an error; otherwise set it to NOERROR. */
2290 *result
= minires_nupdate (&resolver_state
,
2291 ISC_LIST_HEAD (uq
));
2294 print_dns_status ((int)*result
, &uq
);
2297 while (!ISC_LIST_EMPTY (uq
)) {
2298 ns_updrec
*tmp
= ISC_LIST_HEAD (uq
);
2299 ISC_LIST_UNLINK (uq
, tmp
, r_link
);
2300 if (tmp
-> r_data_ephem
) {
2301 dfree (tmp
-> r_data_ephem
, MDL
);
2302 tmp
-> r_data
= (unsigned char *)0;
2303 tmp
-> r_data_ephem
= (unsigned char *)0;
2305 minires_freeupdrec (tmp
);
2308 #endif /* NSUPDATE */
2310 case expr_variable_reference
:
2311 if (scope
&& *scope
) {
2312 binding
= find_binding (*scope
, expr
-> data
.variable
);
2314 if (binding
&& binding
-> value
) {
2315 if (binding
-> value
-> type
== binding_numeric
) {
2316 *result
= binding
-> value
-> value
.intval
;
2319 log_error ("binding type %d in %s.",
2320 binding
-> value
-> type
,
2321 "evaluate_numeric_expression");
2328 #if defined (DEBUG_EXPRESSIONS)
2330 log_debug ("numeric: %s = %ld",
2331 expr
-> data
.variable
, *result
);
2333 log_debug ("numeric: %s = NULL",
2334 expr
-> data
.variable
);
2339 bv
= (struct binding_value
*)0;
2340 status
= evaluate_expression (&bv
, packet
, lease
,
2342 in_options
, cfg_options
,
2345 if (bv
-> type
!= binding_numeric
)
2346 log_error ("%s() returned type %d in %s.",
2347 expr
-> data
.funcall
.name
,
2349 "evaluate_numeric_expression");
2351 *result
= bv
-> value
.intval
;
2352 binding_value_dereference (&bv
, MDL
);
2354 #if defined (DEBUG_EXPRESSIONS)
2355 log_debug ("data: %s = %ld", expr
-> data
.funcall
.name
,
2356 status
? *result
: 0);
2361 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2363 in_options
, cfg_options
,
2365 expr
-> data
.and [0]);
2366 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2368 in_options
, cfg_options
,
2370 expr
-> data
.and [1]);
2372 #if defined (DEBUG_EXPRESSIONS)
2373 if (sleft
&& sright
)
2374 log_debug ("num: %ld + %ld = %ld",
2375 ileft
, iright
, ileft
+ iright
);
2377 log_debug ("num: %ld + NULL = NULL", ileft
);
2379 log_debug ("num: NULL + %ld = NULL", iright
);
2381 if (sleft
&& sright
) {
2382 *result
= ileft
+ iright
;
2388 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2390 in_options
, cfg_options
,
2392 expr
-> data
.and [0]);
2393 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2395 in_options
, cfg_options
,
2397 expr
-> data
.and [1]);
2399 #if defined (DEBUG_EXPRESSIONS)
2400 if (sleft
&& sright
)
2401 log_debug ("num: %ld - %ld = %ld",
2402 ileft
, iright
, ileft
- iright
);
2404 log_debug ("num: %ld - NULL = NULL", ileft
);
2406 log_debug ("num: NULL - %ld = NULL", iright
);
2408 if (sleft
&& sright
) {
2409 *result
= ileft
- iright
;
2415 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2417 in_options
, cfg_options
,
2419 expr
-> data
.and [0]);
2420 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2422 in_options
, cfg_options
,
2424 expr
-> data
.and [1]);
2426 #if defined (DEBUG_EXPRESSIONS)
2427 if (sleft
&& sright
)
2428 log_debug ("num: %ld * %ld = %ld",
2429 ileft
, iright
, ileft
* iright
);
2431 log_debug ("num: %ld * NULL = NULL", ileft
);
2433 log_debug ("num: NULL * %ld = NULL", iright
);
2435 if (sleft
&& sright
) {
2436 *result
= ileft
* iright
;
2442 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2444 in_options
, cfg_options
,
2446 expr
-> data
.and [0]);
2447 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2449 in_options
, cfg_options
,
2451 expr
-> data
.and [1]);
2453 #if defined (DEBUG_EXPRESSIONS)
2454 if (sleft
&& sright
) {
2456 log_debug ("num: %ld / %ld = %ld",
2457 ileft
, iright
, ileft
/ iright
);
2459 log_debug ("num: %ld / %ld = NULL",
2462 log_debug ("num: %ld / NULL = NULL", ileft
);
2464 log_debug ("num: NULL / %ld = NULL", iright
);
2466 if (sleft
&& sright
&& iright
) {
2467 *result
= ileft
/ iright
;
2472 case expr_remainder
:
2473 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2475 in_options
, cfg_options
,
2477 expr
-> data
.and [0]);
2478 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2480 in_options
, cfg_options
,
2482 expr
-> data
.and [1]);
2484 #if defined (DEBUG_EXPRESSIONS)
2485 if (sleft
&& sright
) {
2487 log_debug ("num: %ld %% %ld = %ld",
2488 ileft
, iright
, ileft
% iright
);
2490 log_debug ("num: %ld %% %ld = NULL",
2493 log_debug ("num: %ld %% NULL = NULL", ileft
);
2495 log_debug ("num: NULL %% %ld = NULL", iright
);
2497 if (sleft
&& sright
&& iright
) {
2498 *result
= ileft
% iright
;
2503 case expr_binary_and
:
2504 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2506 in_options
, cfg_options
,
2508 expr
-> data
.and [0]);
2509 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2511 in_options
, cfg_options
,
2513 expr
-> data
.and [1]);
2515 #if defined (DEBUG_EXPRESSIONS)
2516 if (sleft
&& sright
)
2517 log_debug ("num: %ld | %ld = %ld",
2518 ileft
, iright
, ileft
& iright
);
2520 log_debug ("num: %ld & NULL = NULL", ileft
);
2522 log_debug ("num: NULL & %ld = NULL", iright
);
2524 if (sleft
&& sright
) {
2525 *result
= ileft
& iright
;
2530 case expr_binary_or
:
2531 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2533 in_options
, cfg_options
,
2535 expr
-> data
.and [0]);
2536 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2538 in_options
, cfg_options
,
2540 expr
-> data
.and [1]);
2542 #if defined (DEBUG_EXPRESSIONS)
2543 if (sleft
&& sright
)
2544 log_debug ("num: %ld | %ld = %ld",
2545 ileft
, iright
, ileft
| iright
);
2547 log_debug ("num: %ld | NULL = NULL", ileft
);
2549 log_debug ("num: NULL | %ld = NULL", iright
);
2551 if (sleft
&& sright
) {
2552 *result
= ileft
| iright
;
2557 case expr_binary_xor
:
2558 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2560 in_options
, cfg_options
,
2562 expr
-> data
.and [0]);
2563 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2565 in_options
, cfg_options
,
2567 expr
-> data
.and [1]);
2569 #if defined (DEBUG_EXPRESSIONS)
2570 if (sleft
&& sright
)
2571 log_debug ("num: %ld ^ %ld = %ld",
2572 ileft
, iright
, ileft
^ iright
);
2574 log_debug ("num: %ld ^ NULL = NULL", ileft
);
2576 log_debug ("num: NULL ^ %ld = NULL", iright
);
2578 if (sleft
&& sright
) {
2579 *result
= ileft
^ iright
;
2584 case expr_client_state
:
2586 #if defined (DEBUG_EXPRESSIONS)
2587 log_debug ("num: client-state = %d",
2588 client_state
-> state
);
2590 *result
= client_state
-> state
;
2593 #if defined (DEBUG_EXPRESSIONS)
2594 log_debug ("num: client-state = NULL");
2600 case expr_ns_delete
:
2601 case expr_ns_exists
:
2602 case expr_ns_not_exists
:
2603 log_error ("dns opcode in evaluate_numeric_expression: %d",
2608 log_error ("function definition in evaluate_numeric_expr");
2615 log_error ("evaluate_numeric_expression: bogus opcode %d", expr
-> op
);
2619 /* Return data hanging off of an option cache structure, or if there
2620 isn't any, evaluate the expression hanging off of it and return the
2621 result of that evaluation. There should never be both an expression
2622 and a valid data_string. */
2624 int evaluate_option_cache (result
, packet
, lease
, client_state
,
2625 in_options
, cfg_options
, scope
, oc
, file
, line
)
2626 struct data_string
*result
;
2627 struct packet
*packet
;
2628 struct lease
*lease
;
2629 struct client_state
*client_state
;
2630 struct option_state
*in_options
;
2631 struct option_state
*cfg_options
;
2632 struct binding_scope
**scope
;
2633 struct option_cache
*oc
;
2637 if (oc
-> data
.len
) {
2638 data_string_copy (result
, &oc
-> data
, file
, line
);
2641 if (!oc
-> expression
)
2643 return evaluate_data_expression (result
, packet
, lease
, client_state
,
2644 in_options
, cfg_options
, scope
,
2645 oc
-> expression
, file
, line
);
2648 /* Evaluate an option cache and extract a boolean from the result,
2649 returning the boolean. Return false if there is no data. */
2651 int evaluate_boolean_option_cache (ignorep
, packet
,
2652 lease
, client_state
, in_options
,
2653 cfg_options
, scope
, oc
, file
, line
)
2655 struct packet
*packet
;
2656 struct lease
*lease
;
2657 struct client_state
*client_state
;
2658 struct option_state
*in_options
;
2659 struct option_state
*cfg_options
;
2660 struct binding_scope
**scope
;
2661 struct option_cache
*oc
;
2665 struct data_string ds
;
2668 /* So that we can be called with option_lookup as an argument. */
2669 if (!oc
|| !in_options
)
2672 memset (&ds
, 0, sizeof ds
);
2673 if (!evaluate_option_cache (&ds
, packet
,
2674 lease
, client_state
, in_options
,
2675 cfg_options
, scope
, oc
, file
, line
))
2679 result
= ds
.data
[0];
2687 data_string_forget (&ds
, MDL
);
2692 /* Evaluate a boolean expression and return the result of the evaluation,
2693 or FALSE if it failed. */
2695 int evaluate_boolean_expression_result (ignorep
, packet
, lease
, client_state
,
2696 in_options
, cfg_options
, scope
, expr
)
2698 struct packet
*packet
;
2699 struct lease
*lease
;
2700 struct client_state
*client_state
;
2701 struct option_state
*in_options
;
2702 struct option_state
*cfg_options
;
2703 struct binding_scope
**scope
;
2704 struct expression
*expr
;
2708 /* So that we can be called with option_lookup as an argument. */
2712 if (!evaluate_boolean_expression (&result
, packet
, lease
, client_state
,
2713 in_options
, cfg_options
,
2726 /* Dereference an expression node, and if the reference count goes to zero,
2727 dereference any data it refers to, and then free it. */
2728 void expression_dereference (eptr
, file
, line
)
2729 struct expression
**eptr
;
2733 struct expression
*expr
= *eptr
;
2735 /* Zero the pointer. */
2736 *eptr
= (struct expression
*)0;
2738 /* Decrement the reference count. If it's nonzero, we're
2741 rc_register (file
, line
, eptr
, expr
, expr
-> refcnt
, 1, RC_MISC
);
2742 if (expr
-> refcnt
> 0)
2744 if (expr
-> refcnt
< 0) {
2745 log_error ("%s(%d): negative refcnt!", file
, line
);
2746 #if defined (DEBUG_RC_HISTORY)
2747 dump_rc_history (expr
);
2749 #if defined (POINTER_DEBUG)
2756 /* Dereference subexpressions. */
2757 switch (expr
-> op
) {
2758 /* All the binary operators can be handled the same way. */
2760 case expr_not_equal
:
2768 case expr_remainder
:
2769 case expr_binary_and
:
2770 case expr_binary_or
:
2771 case expr_binary_xor
:
2772 case expr_client_state
:
2773 if (expr
-> data
.equal
[0])
2774 expression_dereference (&expr
-> data
.equal
[0],
2776 if (expr
-> data
.equal
[1])
2777 expression_dereference (&expr
-> data
.equal
[1],
2781 case expr_substring
:
2782 if (expr
-> data
.substring
.expr
)
2783 expression_dereference (&expr
-> data
.substring
.expr
,
2785 if (expr
-> data
.substring
.offset
)
2786 expression_dereference (&expr
-> data
.substring
.offset
,
2788 if (expr
-> data
.substring
.len
)
2789 expression_dereference (&expr
-> data
.substring
.len
,
2794 if (expr
-> data
.suffix
.expr
)
2795 expression_dereference (&expr
-> data
.suffix
.expr
,
2797 if (expr
-> data
.suffix
.len
)
2798 expression_dereference (&expr
-> data
.suffix
.len
,
2803 if (expr
-> data
.not)
2804 expression_dereference (&expr
-> data
.not, file
, line
);
2808 if (expr
-> data
.packet
.offset
)
2809 expression_dereference (&expr
-> data
.packet
.offset
,
2811 if (expr
-> data
.packet
.len
)
2812 expression_dereference (&expr
-> data
.packet
.len
,
2816 case expr_extract_int8
:
2817 case expr_extract_int16
:
2818 case expr_extract_int32
:
2819 if (expr
-> data
.extract_int
)
2820 expression_dereference (&expr
-> data
.extract_int
,
2824 case expr_encode_int8
:
2825 case expr_encode_int16
:
2826 case expr_encode_int32
:
2827 if (expr
-> data
.encode_int
)
2828 expression_dereference (&expr
-> data
.encode_int
,
2832 case expr_encapsulate
:
2833 case expr_const_data
:
2834 data_string_forget (&expr
-> data
.const_data
, file
, line
);
2837 case expr_host_lookup
:
2838 if (expr
-> data
.host_lookup
)
2839 dns_host_entry_dereference (&expr
-> data
.host_lookup
,
2843 case expr_binary_to_ascii
:
2844 if (expr
-> data
.b2a
.base
)
2845 expression_dereference (&expr
-> data
.b2a
.base
,
2847 if (expr
-> data
.b2a
.width
)
2848 expression_dereference (&expr
-> data
.b2a
.width
,
2850 if (expr
-> data
.b2a
.seperator
)
2851 expression_dereference (&expr
-> data
.b2a
.seperator
,
2853 if (expr
-> data
.b2a
.buffer
)
2854 expression_dereference (&expr
-> data
.b2a
.buffer
,
2858 case expr_pick_first_value
:
2859 if (expr
-> data
.pick_first_value
.car
)
2860 expression_dereference (&expr
-> data
.pick_first_value
.car
,
2862 if (expr
-> data
.pick_first_value
.cdr
)
2863 expression_dereference (&expr
-> data
.pick_first_value
.cdr
,
2868 if (expr
-> data
.reverse
.width
)
2869 expression_dereference (&expr
-> data
.reverse
.width
,
2871 if (expr
-> data
.reverse
.buffer
)
2872 expression_dereference
2873 (&expr
-> data
.reverse
.buffer
, file
, line
);
2876 case expr_dns_transaction
:
2877 if (expr
-> data
.dns_transaction
.car
)
2878 expression_dereference (&expr
-> data
.dns_transaction
.car
,
2880 if (expr
-> data
.dns_transaction
.cdr
)
2881 expression_dereference (&expr
-> data
.dns_transaction
.cdr
,
2886 if (expr
-> data
.ns_add
.rrname
)
2887 expression_dereference (&expr
-> data
.ns_add
.rrname
,
2889 if (expr
-> data
.ns_add
.rrdata
)
2890 expression_dereference (&expr
-> data
.ns_add
.rrdata
,
2892 if (expr
-> data
.ns_add
.ttl
)
2893 expression_dereference (&expr
-> data
.ns_add
.ttl
,
2897 case expr_ns_delete
:
2898 case expr_ns_exists
:
2899 case expr_ns_not_exists
:
2900 if (expr
-> data
.ns_delete
.rrname
)
2901 expression_dereference (&expr
-> data
.ns_delete
.rrname
,
2903 if (expr
-> data
.ns_delete
.rrdata
)
2904 expression_dereference (&expr
-> data
.ns_delete
.rrdata
,
2908 case expr_variable_reference
:
2909 case expr_variable_exists
:
2910 if (expr
-> data
.variable
)
2911 dfree (expr
-> data
.variable
, file
, line
);
2915 if (expr
-> data
.funcall
.name
)
2916 dfree (expr
-> data
.funcall
.name
, file
, line
);
2917 if (expr
-> data
.funcall
.arglist
)
2918 expression_dereference (&expr
-> data
.funcall
.arglist
,
2923 if (expr
-> data
.arg
.val
)
2924 expression_dereference (&expr
-> data
.arg
.val
,
2926 if (expr
-> data
.arg
.next
)
2927 expression_dereference (&expr
-> data
.arg
.next
,
2932 fundef_dereference (&expr
-> data
.func
, file
, line
);
2935 /* No subexpressions. */
2936 case expr_leased_address
:
2937 case expr_lease_time
:
2940 case expr_const_int
:
2952 free_expression (expr
, MDL
);
2955 int is_dns_expression (expr
)
2956 struct expression
*expr
;
2958 return (expr
-> op
== expr_ns_add
||
2959 expr
-> op
== expr_ns_delete
||
2960 expr
-> op
== expr_ns_exists
||
2961 expr
-> op
== expr_ns_not_exists
);
2964 int is_boolean_expression (expr
)
2965 struct expression
*expr
;
2967 return (expr
-> op
== expr_check
||
2968 expr
-> op
== expr_exists
||
2969 expr
-> op
== expr_variable_exists
||
2970 expr
-> op
== expr_equal
||
2971 expr
-> op
== expr_not_equal
||
2972 expr
-> op
== expr_and
||
2973 expr
-> op
== expr_or
||
2974 expr
-> op
== expr_not
||
2975 expr
-> op
== expr_known
||
2976 expr
-> op
== expr_static
);
2979 int is_data_expression (expr
)
2980 struct expression
*expr
;
2982 return (expr
-> op
== expr_substring
||
2983 expr
-> op
== expr_suffix
||
2984 expr
-> op
== expr_option
||
2985 expr
-> op
== expr_hardware
||
2986 expr
-> op
== expr_const_data
||
2987 expr
-> op
== expr_packet
||
2988 expr
-> op
== expr_concat
||
2989 expr
-> op
== expr_encapsulate
||
2990 expr
-> op
== expr_encode_int8
||
2991 expr
-> op
== expr_encode_int16
||
2992 expr
-> op
== expr_encode_int32
||
2993 expr
-> op
== expr_host_lookup
||
2994 expr
-> op
== expr_binary_to_ascii
||
2995 expr
-> op
== expr_filename
||
2996 expr
-> op
== expr_sname
||
2997 expr
-> op
== expr_reverse
||
2998 expr
-> op
== expr_pick_first_value
||
2999 expr
-> op
== expr_host_decl_name
||
3000 expr
-> op
== expr_leased_address
||
3001 expr
-> op
== expr_config_option
||
3002 expr
-> op
== expr_null
);
3005 int is_numeric_expression (expr
)
3006 struct expression
*expr
;
3008 return (expr
-> op
== expr_extract_int8
||
3009 expr
-> op
== expr_extract_int16
||
3010 expr
-> op
== expr_extract_int32
||
3011 expr
-> op
== expr_const_int
||
3012 expr
-> op
== expr_lease_time
||
3013 expr
-> op
== expr_dns_transaction
||
3014 expr
-> op
== expr_add
||
3015 expr
-> op
== expr_subtract
||
3016 expr
-> op
== expr_multiply
||
3017 expr
-> op
== expr_divide
||
3018 expr
-> op
== expr_remainder
||
3019 expr
-> op
== expr_binary_and
||
3020 expr
-> op
== expr_binary_or
||
3021 expr
-> op
== expr_binary_xor
||
3022 expr
-> op
== expr_client_state
);
3025 int is_compound_expression (expr
)
3026 struct expression
*expr
;
3028 return (expr
-> op
== expr_ns_add
||
3029 expr
-> op
== expr_ns_delete
||
3030 expr
-> op
== expr_ns_exists
||
3031 expr
-> op
== expr_ns_not_exists
||
3032 expr
-> op
== expr_substring
||
3033 expr
-> op
== expr_suffix
||
3034 expr
-> op
== expr_option
||
3035 expr
-> op
== expr_concat
||
3036 expr
-> op
== expr_encode_int8
||
3037 expr
-> op
== expr_encode_int16
||
3038 expr
-> op
== expr_encode_int32
||
3039 expr
-> op
== expr_binary_to_ascii
||
3040 expr
-> op
== expr_reverse
||
3041 expr
-> op
== expr_pick_first_value
||
3042 expr
-> op
== expr_config_option
||
3043 expr
-> op
== expr_extract_int8
||
3044 expr
-> op
== expr_extract_int16
||
3045 expr
-> op
== expr_extract_int32
||
3046 expr
-> op
== expr_dns_transaction
);
3049 static int op_val
PROTO ((enum expr_op
));
3051 static int op_val (op
)
3059 case expr_substring
:
3062 case expr_encapsulate
:
3063 case expr_host_lookup
:
3068 case expr_const_data
:
3069 case expr_extract_int8
:
3070 case expr_extract_int16
:
3071 case expr_extract_int32
:
3072 case expr_encode_int8
:
3073 case expr_encode_int16
:
3074 case expr_encode_int32
:
3075 case expr_const_int
:
3077 case expr_variable_exists
:
3079 case expr_binary_to_ascii
:
3083 case expr_pick_first_value
:
3084 case expr_host_decl_name
:
3085 case expr_config_option
:
3086 case expr_leased_address
:
3087 case expr_lease_time
:
3088 case expr_dns_transaction
:
3090 case expr_variable_reference
:
3092 case expr_ns_delete
:
3093 case expr_ns_exists
:
3094 case expr_ns_not_exists
:
3098 /* XXXDPN: Need to assign sane precedences to these. */
3099 case expr_binary_and
:
3100 case expr_binary_or
:
3101 case expr_binary_xor
:
3102 case expr_client_state
:
3106 case expr_not_equal
:
3119 case expr_remainder
:
3125 int op_precedence (op1
, op2
)
3126 enum expr_op op1
, op2
;
3130 return op_val (op1
) - op_val (op2
);
3133 enum expression_context
expression_context (struct expression
*expr
)
3135 if (is_data_expression (expr
))
3136 return context_data
;
3137 if (is_numeric_expression (expr
))
3138 return context_numeric
;
3139 if (is_boolean_expression (expr
))
3140 return context_boolean
;
3141 if (is_dns_expression (expr
))
3146 enum expression_context
op_context (op
)
3150 /* XXX Why aren't these specific? */
3155 case expr_substring
:
3158 case expr_encapsulate
:
3159 case expr_host_lookup
:
3164 case expr_const_data
:
3165 case expr_extract_int8
:
3166 case expr_extract_int16
:
3167 case expr_extract_int32
:
3168 case expr_encode_int8
:
3169 case expr_encode_int16
:
3170 case expr_encode_int32
:
3171 case expr_const_int
:
3173 case expr_variable_exists
:
3175 case expr_binary_to_ascii
:
3179 case expr_pick_first_value
:
3180 case expr_host_decl_name
:
3181 case expr_config_option
:
3182 case expr_leased_address
:
3183 case expr_lease_time
:
3185 case expr_variable_reference
:
3187 case expr_ns_delete
:
3188 case expr_ns_exists
:
3189 case expr_ns_not_exists
:
3190 case expr_dns_transaction
:
3197 case expr_not_equal
:
3198 return context_data
;
3201 return context_boolean
;
3204 return context_boolean
;
3210 case expr_remainder
:
3211 case expr_binary_and
:
3212 case expr_binary_or
:
3213 case expr_binary_xor
:
3214 case expr_client_state
:
3215 return context_numeric
;
3220 int write_expression (file
, expr
, col
, indent
, firstp
)
3222 struct expression
*expr
;
3227 struct expression
*e
;
3233 /* If this promises to be a fat expression, start a new line. */
3234 if (!firstp
&& is_compound_expression (expr
)) {
3235 indent_spaces (file
, indent
);
3239 switch (expr
-> op
) {
3241 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3245 col
= token_print_indent (file
, col
, indent
, "", "", "check");
3246 col
= token_print_indent_concat (file
, col
, indent
,
3248 expr
-> data
.check
-> name
,
3252 case expr_not_equal
:
3259 col
= write_expression (file
, expr
-> data
.equal
[0],
3261 col
= token_print_indent (file
, col
, indent
, " ", " ", s
);
3262 col
= write_expression (file
, expr
-> data
.equal
[1],
3263 col
, indent
+ 2, 0);
3266 case expr_substring
:
3267 col
= token_print_indent (file
, col
, indent
, "", "",
3269 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3271 col
= write_expression (file
, expr
-> data
.substring
.expr
,
3273 col
= token_print_indent (file
, col
, indent
, "", " ", ",");
3274 col
= write_expression (file
, expr
-> data
.substring
.offset
,
3276 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3277 col
= write_expression (file
, expr
-> data
.substring
.len
,
3279 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3283 col
= token_print_indent (file
, col
, indent
, "", "", "suffix");
3284 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3286 col
= write_expression (file
, expr
-> data
.suffix
.expr
,
3288 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3289 col
= write_expression (file
, expr
-> data
.suffix
.len
,
3291 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3296 col
= token_print_indent (file
, col
, indent
, "", "",
3298 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3302 col
= write_expression (file
, e
-> data
.concat
[0],
3305 if (!e
-> data
.concat
[1])
3307 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3308 if (e
-> data
.concat
[1] -> op
== expr_concat
) {
3309 e
= e
-> data
.concat
[1];
3312 col
= write_expression (file
, e
-> data
.concat
[1],
3315 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3318 case expr_host_lookup
:
3319 col
= token_print_indent (file
, col
, indent
, "", "",
3321 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3322 col
= token_print_indent_concat
3323 (file
, col
, indent
, "", "",
3324 "\"", expr
-> data
.host_lookup
-> hostname
, "\"",
3326 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3345 case expr_remainder
:
3349 case expr_binary_and
:
3353 case expr_binary_or
:
3357 case expr_binary_xor
:
3370 col
= token_print_indent (file
, col
, indent
, "", " ", "not");
3371 col
= write_expression (file
,
3372 expr
-> data
.not, col
, indent
+ 2, 1);
3379 col
= token_print_indent (file
, col
, indent
, "", "", s
);
3381 if (expr
-> data
.option
-> universe
!= &dhcp_universe
) {
3382 col
= token_print_indent (file
, col
, indent
,
3384 (expr
-> data
.option
->
3386 col
= token_print_indent (file
, col
, indent
, "", "",
3388 col
= token_print_indent (file
, col
, indent
, "", "",
3389 expr
-> data
.option
-> name
);
3391 col
= token_print_indent (file
, col
, indent
, " ", "",
3392 expr
-> data
.option
-> name
);
3397 col
= token_print_indent (file
, col
, indent
, "", "",
3402 col
= token_print_indent (file
, col
, indent
, "", "",
3404 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3406 col
= write_expression (file
, expr
-> data
.packet
.offset
,
3408 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3409 col
= write_expression (file
, expr
-> data
.packet
.len
,
3411 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3414 case expr_const_data
:
3415 col
= token_indent_data_string (file
, col
, indent
, "", "",
3416 &expr
-> data
.const_data
);
3419 case expr_extract_int8
:
3422 col
= token_print_indent (file
, col
, indent
, "", "",
3424 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3426 col
= write_expression (file
, expr
-> data
.extract_int
,
3428 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3429 sprintf (obuf
, "%d", width
);
3430 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3431 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3434 case expr_extract_int16
:
3438 case expr_extract_int32
:
3442 case expr_encode_int8
:
3445 col
= token_print_indent (file
, col
, indent
, "", "",
3447 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3449 col
= write_expression (file
, expr
-> data
.extract_int
,
3451 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3452 sprintf (obuf
, "%d", width
);
3453 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3454 col
= token_print_indent (file
, col
, indent
, "", "",
3458 case expr_encode_int16
:
3462 case expr_encode_int32
:
3466 case expr_const_int
:
3467 sprintf (obuf
, "%lu", expr
-> data
.const_int
);
3468 col
= token_print_indent (file
, col
, indent
, "", "", obuf
);
3473 goto print_option_name
;
3475 case expr_encapsulate
:
3476 col
= token_print_indent (file
, col
, indent
, "", "",
3478 col
= token_indent_data_string (file
, col
, indent
, " ", "",
3479 &expr
-> data
.encapsulate
);
3483 col
= token_print_indent (file
, col
, indent
, "", "", "known");
3487 col
= token_print_indent (file
, col
, indent
, "", "",
3489 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3491 col
= write_expression (file
, expr
-> data
.reverse
.width
,
3493 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3494 col
= write_expression (file
, expr
-> data
.reverse
.buffer
,
3496 col
= token_print_indent (file
, col
, indent
, "", "",
3500 case expr_leased_address
:
3501 col
= token_print_indent (file
, col
, indent
, "", "",
3505 case expr_client_state
:
3506 col
= token_print_indent (file
, col
, indent
, "", "",
3510 case expr_binary_to_ascii
:
3511 col
= token_print_indent (file
, col
, indent
, "", "",
3513 col
= token_print_indent (file
, col
, indent
, " ", "",
3516 col
= write_expression (file
, expr
-> data
.b2a
.base
,
3518 col
= token_print_indent (file
, col
, scol
, "", " ",
3520 col
= write_expression (file
, expr
-> data
.b2a
.width
,
3522 col
= token_print_indent (file
, col
, scol
, "", " ",
3524 col
= write_expression (file
, expr
-> data
.b2a
.seperator
,
3526 col
= token_print_indent (file
, col
, scol
, "", " ",
3528 col
= write_expression (file
, expr
-> data
.b2a
.buffer
,
3530 col
= token_print_indent (file
, col
, indent
, "", "",
3534 case expr_config_option
:
3535 s
= "config-option";
3536 goto print_option_name
;
3538 case expr_host_decl_name
:
3539 col
= token_print_indent (file
, col
, indent
, "", "",
3543 case expr_pick_first_value
:
3545 col
= token_print_indent (file
, col
, indent
, "", "",
3547 col
= token_print_indent (file
, col
, indent
, " ", "",
3552 col
= write_expression (file
,
3553 e
-> data
.pick_first_value
.car
,
3556 /* We're being very lisp-like right now - instead of
3557 representing this expression as (first middle . last) we're
3558 representing it as (first middle last), which means that the
3559 tail cdr is always nil. Apologies to non-wisp-lizards - may
3560 this obscure way of describing the problem motivate you to
3561 learn more about the one true computing language. */
3562 if (!e
-> data
.pick_first_value
.cdr
)
3564 col
= token_print_indent (file
, col
, scol
, "", " ",
3566 if (e
-> data
.pick_first_value
.cdr
-> op
==
3567 expr_pick_first_value
) {
3568 e
= e
-> data
.pick_first_value
.cdr
;
3571 col
= write_expression (file
,
3572 e
-> data
.pick_first_value
.cdr
,
3575 col
= token_print_indent (file
, col
, indent
, "", "",
3579 case expr_lease_time
:
3580 col
= token_print_indent (file
, col
, indent
, "", "",
3584 case expr_dns_transaction
:
3585 col
= token_print_indent (file
, col
, indent
, "", "",
3587 col
= token_print_indent (file
, col
, indent
, " ", "",
3591 e
&& e
-> op
== expr_dns_transaction
;
3592 e
= e
-> data
.dns_transaction
.cdr
) {
3598 col
= write_expression (file
,
3599 e
-> data
.dns_transaction
.car
,
3601 if (e
-> data
.dns_transaction
.cdr
)
3602 col
= token_print_indent (file
, col
, scol
,
3606 col
= write_expression (file
, e
, col
, scol
, 0);
3607 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3611 col
= token_print_indent (file
, col
, indent
, "", "",
3613 col
= token_print_indent (file
, col
, indent
, " ", "",
3616 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3617 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3618 col
= token_print_indent (file
, col
, scol
, "", " ",
3620 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3621 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3622 col
= token_print_indent (file
, col
, scol
, "", " ",
3624 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3626 col
= token_print_indent (file
, col
, scol
, "", " ",
3628 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3630 col
= token_print_indent (file
, col
, scol
, "", " ",
3632 col
= write_expression (file
, expr
-> data
.ns_add
.ttl
,
3634 col
= token_print_indent (file
, col
, indent
, "", "",
3638 case expr_ns_delete
:
3639 col
= token_print_indent (file
, col
, indent
, "", "",
3641 col
= token_print_indent (file
, col
, indent
, " ", "",
3645 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3646 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3647 col
= token_print_indent (file
, col
, scol
, "", " ",
3649 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3650 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3651 col
= token_print_indent (file
, col
, scol
, "", " ",
3653 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3655 col
= token_print_indent (file
, col
, scol
, "", " ",
3657 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3659 col
= token_print_indent (file
, col
, indent
, "", "",
3663 case expr_ns_exists
:
3664 col
= token_print_indent (file
, col
, indent
, "", "",
3666 col
= token_print_indent (file
, col
, indent
, " ", "",
3668 goto finish_ns_small
;
3670 case expr_ns_not_exists
:
3671 col
= token_print_indent (file
, col
, indent
, "", "",
3673 col
= token_print_indent (file
, col
, indent
, " ", "",
3675 goto finish_ns_small
;
3678 col
= token_print_indent (file
, col
, indent
, "", "",
3683 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3686 case expr_variable_reference
:
3687 col
= token_print_indent (file
, indent
, indent
, "", "",
3688 expr
-> data
.variable
);
3691 case expr_variable_exists
:
3692 col
= token_print_indent (file
, indent
, indent
, "", "",
3694 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3695 col
= token_print_indent (file
, col
, indent
, "", "",
3696 expr
-> data
.variable
);
3697 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3701 log_fatal ("invalid expression type in print_expression: %d",
3707 struct binding
*find_binding (struct binding_scope
*scope
, const char *name
)
3710 struct binding_scope
*s
;
3712 for (s
= scope
; s
; s
= s
-> outer
) {
3713 for (bp
= s
-> bindings
; bp
; bp
= bp
-> next
) {
3714 if (!strcasecmp (name
, bp
-> name
)) {
3719 return (struct binding
*)0;
3722 int free_bindings (struct binding_scope
*scope
, const char *file
, int line
)
3724 struct binding
*bp
, *next
;
3726 for (bp
= scope
-> bindings
; bp
; bp
= next
) {
3729 dfree (bp
-> name
, file
, line
);
3731 binding_value_dereference (&bp
-> value
, file
, line
);
3732 dfree (bp
, file
, line
);
3734 scope
-> bindings
= (struct binding
*)0;
3738 int binding_scope_dereference (ptr
, file
, line
)
3739 struct binding_scope
**ptr
;
3744 struct binding_scope
*binding_scope
;
3746 if (!ptr
|| !*ptr
) {
3747 log_error ("%s(%d): null pointer", file
, line
);
3748 #if defined (POINTER_DEBUG)
3755 binding_scope
= *ptr
;
3756 *ptr
= (struct binding_scope
*)0;
3757 --binding_scope
-> refcnt
;
3758 rc_register (file
, line
, ptr
,
3759 binding_scope
, binding_scope
-> refcnt
, 1, RC_MISC
);
3760 if (binding_scope
-> refcnt
> 0)
3763 if (binding_scope
-> refcnt
< 0) {
3764 log_error ("%s(%d): negative refcnt!", file
, line
);
3765 #if defined (DEBUG_RC_HISTORY)
3766 dump_rc_history (binding_scope
);
3768 #if defined (POINTER_DEBUG)
3775 free_bindings (binding_scope
, file
, line
);
3776 if (binding_scope
-> outer
)
3777 binding_scope_dereference (&binding_scope
-> outer
, MDL
);
3778 dfree (binding_scope
, file
, line
);
3782 int fundef_dereference (ptr
, file
, line
)
3783 struct fundef
**ptr
;
3787 struct fundef
*bp
= *ptr
;
3788 struct string_list
*sp
, *next
;
3791 log_error ("%s(%d): null pointer", file
, line
);
3792 #if defined (POINTER_DEBUG)
3800 log_error ("%s(%d): null pointer", file
, line
);
3801 #if defined (POINTER_DEBUG)
3809 rc_register (file
, line
, ptr
, bp
, bp
-> refcnt
, 1, RC_MISC
);
3810 if (bp
-> refcnt
< 0) {
3811 log_error ("%s(%d): negative refcnt!", file
, line
);
3812 #if defined (DEBUG_RC_HISTORY)
3813 dump_rc_history (bp
);
3815 #if defined (POINTER_DEBUG)
3821 if (!bp
-> refcnt
) {
3822 for (sp
= bp
-> args
; sp
; sp
= next
) {
3824 dfree (sp
, file
, line
);
3826 if (bp
-> statements
)
3827 executable_statement_dereference (&bp
-> statements
,
3829 dfree (bp
, file
, line
);
3831 *ptr
= (struct fundef
*)0;
3835 #if defined (NOTYET) /* Post 3.0 final. */
3836 int data_subexpression_length (int *rv
,
3837 struct expression
*expr
)
3839 int crhs
, clhs
, llhs
, lrhs
;
3840 switch (expr
-> op
) {
3841 case expr_substring
:
3842 if (expr
-> data
.substring
.len
&&
3843 expr
-> data
.substring
.len
-> op
== expr_const_int
) {
3845 (int)expr
-> data
.substring
.len
-> data
.const_int
);
3852 if (expr
-> data
.suffix
.len
&&
3853 expr
-> data
.suffix
.len
-> op
== expr_const_int
) {
3855 (int)expr
-> data
.suffix
.len
-> data
.const_int
);
3861 clhs
= data_subexpression_length (&llhs
,
3862 expr
-> data
.concat
[0]);
3863 crhs
= data_subexpression_length (&lrhs
,
3864 expr
-> data
.concat
[1]);
3865 if (crhs
== 0 || clhs
== 0)
3874 case expr_const_data
:
3875 *rv
= expr
-> data
.const_data
.len
;
3879 return data_subexpression_length (rv
,
3880 expr
-> data
.reverse
.buffer
);
3882 case expr_leased_address
:
3883 case expr_lease_time
:
3887 case expr_pick_first_value
:
3888 clhs
= data_subexpression_length (&llhs
,
3889 expr
-> data
.concat
[0]);
3890 crhs
= data_subexpression_length (&lrhs
,
3891 expr
-> data
.concat
[1]);
3892 if (crhs
== 0 || clhs
== 0)
3900 case expr_binary_to_ascii
:
3901 case expr_config_option
:
3902 case expr_host_decl_name
:
3903 case expr_encapsulate
:
3906 case expr_host_lookup
:
3915 case expr_extract_int8
:
3916 case expr_extract_int16
:
3917 case expr_extract_int32
:
3918 case expr_encode_int8
:
3919 case expr_encode_int16
:
3920 case expr_encode_int32
:
3921 case expr_const_int
:
3924 case expr_dns_transaction
:
3927 case expr_ns_delete
:
3928 case expr_ns_exists
:
3929 case expr_ns_not_exists
:
3930 case expr_not_equal
:
3932 case expr_variable_exists
:
3933 case expr_variable_reference
:
3941 case expr_remainder
:
3942 case expr_binary_and
:
3943 case expr_binary_or
:
3944 case expr_binary_xor
:
3945 case expr_client_state
:
3951 int expr_valid_for_context (struct expression
*expr
,
3952 enum expression_context context
)
3954 /* We don't know at parse time what type of value a function may
3955 return, so we can't flag an error on it. */
3956 if (expr
-> op
== expr_funcall
||
3957 expr
-> op
== expr_variable_reference
)
3964 case context_boolean
:
3965 if (is_boolean_expression (expr
))
3970 if (is_data_expression (expr
))
3974 case context_numeric
:
3975 if (is_numeric_expression (expr
))
3980 if (is_dns_expression (expr
)) {
3985 case context_data_or_numeric
:
3986 if (is_numeric_expression (expr
) ||
3987 is_data_expression (expr
)) {
3992 case context_function
:
3993 if (expr
-> op
== expr_function
)
4001 struct binding
*create_binding (struct binding_scope
**scope
, const char *name
)
4003 struct binding
*binding
;
4006 if (!binding_scope_allocate (scope
, MDL
))
4007 return (struct binding
*)0;
4010 binding
= find_binding (*scope
, name
);
4012 binding
= dmalloc (sizeof *binding
, MDL
);
4014 return (struct binding
*)0;
4016 memset (binding
, 0, sizeof *binding
);
4017 binding
-> name
= dmalloc (strlen (name
) + 1, MDL
);
4018 if (!binding
-> name
) {
4019 dfree (binding
, MDL
);
4020 return (struct binding
*)0;
4022 strcpy (binding
-> name
, name
);
4024 binding
-> next
= (*scope
) -> bindings
;
4025 (*scope
) -> bindings
= binding
;
4032 int bind_ds_value (struct binding_scope
**scope
,
4034 struct data_string
*value
)
4036 struct binding
*binding
;
4038 binding
= create_binding (scope
, name
);
4042 if (binding
-> value
)
4043 binding_value_dereference (&binding
-> value
, MDL
);
4045 if (!binding_value_allocate (&binding
-> value
, MDL
))
4048 data_string_copy (&binding
-> value
-> value
.data
, value
, MDL
);
4049 binding
-> value
-> type
= binding_data
;
4055 int find_bound_string (struct data_string
*value
,
4056 struct binding_scope
*scope
,
4059 struct binding
*binding
;
4061 binding
= find_binding (scope
, name
);
4063 !binding
-> value
||
4064 binding
-> value
-> type
!= binding_data
)
4067 if (binding
-> value
-> value
.data
.terminated
) {
4068 data_string_copy (value
, &binding
-> value
-> value
.data
, MDL
);
4070 buffer_allocate (&value
-> buffer
,
4071 binding
-> value
-> value
.data
.len
,
4073 if (!value
-> buffer
)
4076 memcpy (value
-> buffer
-> data
,
4077 binding
-> value
-> value
.data
.data
,
4078 binding
-> value
-> value
.data
.len
);
4079 value
-> data
= value
-> buffer
-> data
;
4080 value
-> len
= binding
-> value
-> value
.data
.len
;
4086 int unset (struct binding_scope
*scope
, const char *name
)
4088 struct binding
*binding
;
4090 binding
= find_binding (scope
, name
);
4092 if (binding
-> value
)
4093 binding_value_dereference
4094 (&binding
-> value
, MDL
);
4100 /* vim: set tabstop=8: */