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.6 2005/08/11 17:13:21 drochner 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
;
253 /* Allocate a node to enforce a limit on evaluation. */
254 if (!expression_allocate (new, MDL
))
255 log_error ("no memory for limit expression");
256 (*new) -> op
= expr_substring
;
257 expression_reference (&(*new) -> data
.substring
.expr
, expr
, MDL
);
259 /* Offset is a constant 0. */
260 if (!expression_allocate (&(*new) -> data
.substring
.offset
, MDL
)) {
261 log_error ("no memory for limit offset expression");
262 expression_dereference (new, MDL
);
265 (*new) -> data
.substring
.offset
-> op
= expr_const_int
;
266 (*new) -> data
.substring
.offset
-> data
.const_int
= 0;
268 /* Length is a constant: the specified limit. */
269 if (!expression_allocate (&(*new) -> data
.substring
.len
, MDL
)) {
270 log_error ("no memory for limit length expression");
271 expression_dereference (new, MDL
);
274 (*new) -> data
.substring
.len
-> op
= expr_const_int
;
275 (*new) -> data
.substring
.len
-> data
.const_int
= limit
;
280 int option_cache (struct option_cache
**oc
, struct data_string
*dp
,
281 struct expression
*expr
, struct option
*option
,
282 const char *file
, int line
)
284 if (!option_cache_allocate (oc
, file
, line
))
287 data_string_copy (&(*oc
) -> data
, dp
, file
, line
);
289 expression_reference (&(*oc
) -> expression
, expr
, file
, line
);
290 (*oc
) -> option
= option
;
294 int make_let (result
, name
)
295 struct executable_statement
**result
;
298 if (!(executable_statement_allocate (result
, MDL
)))
301 (*result
) -> op
= let_statement
;
302 (*result
) -> data
.let
.name
= dmalloc (strlen (name
) + 1, MDL
);
303 if (!(*result
) -> data
.let
.name
) {
304 executable_statement_dereference (result
, MDL
);
307 strcpy ((*result
) -> data
.let
.name
, name
);
311 static int do_host_lookup (result
, dns
)
312 struct data_string
*result
;
313 struct dns_host_entry
*dns
;
320 log_debug ("time: now = %d dns = %d diff = %d",
321 cur_time
, dns
-> timeout
, cur_time
- dns
-> timeout
);
324 /* If the record hasn't timed out, just copy the data and return. */
325 if (cur_time
<= dns
-> timeout
) {
327 log_debug ("easy copy: %d %s",
330 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
))
333 data_string_copy (result
, &dns
-> data
, MDL
);
337 log_debug ("Looking up %s", dns
-> hostname
);
340 /* Otherwise, look it up... */
341 h
= gethostbyname (dns
-> hostname
);
347 log_error ("%s: host unknown.", dns
-> hostname
);
351 log_error ("%s: temporary name server failure",
355 log_error ("%s: name server failed", dns
-> hostname
);
358 log_error ("%s: no A record associated with address",
361 #endif /* !NO_H_ERRNO */
363 /* Okay to try again after a minute. */
364 dns
-> timeout
= cur_time
+ 60;
365 data_string_forget (&dns
-> data
, MDL
);
370 log_debug ("Lookup succeeded; first address is %s",
371 inet_ntoa (h
-> h_addr_list
[0]));
374 /* Count the number of addresses we got... */
375 for (count
= 0; h
-> h_addr_list
[count
]; count
++)
378 /* Dereference the old data, if any. */
379 data_string_forget (&dns
-> data
, MDL
);
381 /* Do we need to allocate more memory? */
382 new_len
= count
* h
-> h_length
;
383 if (!buffer_allocate (&dns
-> data
.buffer
, new_len
, MDL
))
385 log_error ("No memory for %s.", dns
-> hostname
);
389 dns
-> data
.data
= &dns
-> data
.buffer
-> data
[0];
390 dns
-> data
.len
= new_len
;
391 dns
-> data
.terminated
= 0;
393 /* Addresses are conveniently stored one to the buffer, so we
394 have to copy them out one at a time... :'( */
395 for (i
= 0; i
< count
; i
++) {
396 memcpy (&dns
-> data
.buffer
-> data
[h
-> h_length
* i
],
397 h
-> h_addr_list
[i
], (unsigned)(h
-> h_length
));
400 log_debug ("dns -> data: %x h -> h_addr_list [0]: %x",
401 *(int *)(dns
-> buffer
), h
-> h_addr_list
[0]);
404 /* XXX Set the timeout for an hour from now.
405 XXX This should really use the time on the DNS reply. */
406 dns
-> timeout
= cur_time
+ 3600;
409 log_debug ("hard copy: %d %s", dns
-> data
.len
,
411 ? inet_ntoa (*(struct in_addr
*)(dns
-> data
.data
)) : 0));
413 data_string_copy (result
, &dns
-> data
, MDL
);
417 int evaluate_expression (result
, packet
, lease
, client_state
,
418 in_options
, cfg_options
, scope
, expr
, file
, line
)
419 struct binding_value
**result
;
420 struct packet
*packet
;
422 struct client_state
*client_state
;
423 struct option_state
*in_options
;
424 struct option_state
*cfg_options
;
425 struct binding_scope
**scope
;
426 struct expression
*expr
;
430 struct binding_value
*bv
;
432 struct binding
*binding
;
434 bv
= (struct binding_value
*)0;
436 if (expr
-> op
== expr_variable_reference
) {
437 if (!scope
|| !*scope
)
440 binding
= find_binding (*scope
, expr
-> data
.variable
);
442 if (binding
&& binding
-> value
) {
444 binding_value_reference (result
,
450 } else if (expr
-> op
== expr_funcall
) {
451 struct string_list
*s
;
452 struct expression
*arg
;
453 struct binding_scope
*ns
;
456 if (!scope
|| !*scope
) {
457 log_error ("%s: no such function.",
458 expr
-> data
.funcall
.name
);
462 binding
= find_binding (*scope
, expr
-> data
.funcall
.name
);
464 if (!binding
|| !binding
-> value
) {
465 log_error ("%s: no such function.",
466 expr
-> data
.funcall
.name
);
469 if (binding
-> value
-> type
!= binding_function
) {
470 log_error ("%s: not a function.",
471 expr
-> data
.funcall
.name
);
475 /* Create a new binding scope in which to define
476 the arguments to the function. */
477 ns
= (struct binding_scope
*)0;
478 if (!binding_scope_allocate (&ns
, MDL
)) {
479 log_error ("%s: can't allocate argument scope.",
480 expr
-> data
.funcall
.name
);
484 arg
= expr
-> data
.funcall
.arglist
;
485 s
= binding
-> value
-> value
.fundef
-> args
;
487 nb
= dmalloc (sizeof *nb
, MDL
);
490 binding_scope_dereference (&ns
, MDL
);
493 memset (nb
, 0, sizeof *nb
);
494 nb
-> name
= dmalloc (strlen (s
-> string
) + 1,
497 strcpy (nb
-> name
, s
-> string
);
500 nb
= (struct binding
*)0;
504 evaluate_expression (&nb
-> value
, packet
, lease
,
506 in_options
, cfg_options
, scope
,
507 arg
-> data
.arg
.val
, file
, line
);
508 nb
-> next
= ns
-> bindings
;
510 arg
= arg
-> data
.arg
.next
;
514 log_error ("%s: too many arguments.",
515 expr
-> data
.funcall
.name
);
516 binding_scope_dereference (&ns
, MDL
);
520 log_error ("%s: too few arguments.",
521 expr
-> data
.funcall
.name
);
522 binding_scope_dereference (&ns
, MDL
);
527 binding_scope_reference (&ns
-> outer
, *scope
, MDL
);
529 status
= (execute_statements
531 lease
, client_state
, in_options
, cfg_options
, &ns
,
532 binding
-> value
-> value
.fundef
-> statements
));
533 binding_scope_dereference (&ns
, MDL
);
537 } else if (is_boolean_expression (expr
)) {
538 if (!binding_value_allocate (&bv
, MDL
))
540 bv
-> type
= binding_boolean
;
541 status
= (evaluate_boolean_expression
542 (&bv
-> value
.boolean
, packet
, lease
, client_state
,
543 in_options
, cfg_options
, scope
, expr
));
544 } else if (is_numeric_expression (expr
)) {
545 if (!binding_value_allocate (&bv
, MDL
))
547 bv
-> type
= binding_numeric
;
548 status
= (evaluate_numeric_expression
549 (&bv
-> value
.intval
, packet
, lease
, client_state
,
550 in_options
, cfg_options
, scope
, expr
));
551 } else if (is_data_expression (expr
)) {
552 if (!binding_value_allocate (&bv
, MDL
))
554 bv
-> type
= binding_data
;
555 status
= (evaluate_data_expression
556 (&bv
-> value
.data
, packet
, lease
, client_state
,
557 in_options
, cfg_options
, scope
, expr
, MDL
));
558 } else if (is_dns_expression (expr
)) {
559 #if defined (NSUPDATE)
560 if (!binding_value_allocate (&bv
, MDL
))
562 bv
-> type
= binding_dns
;
563 status
= (evaluate_dns_expression
564 (&bv
-> value
.dns
, packet
, lease
, client_state
,
565 in_options
, cfg_options
, scope
, expr
));
568 log_error ("%s: invalid expression type: %d",
569 "evaluate_expression", expr
-> op
);
572 if (result
&& status
)
573 binding_value_reference (result
, bv
, file
, line
);
574 binding_value_dereference (&bv
, MDL
);
579 int binding_value_dereference (struct binding_value
**v
,
580 const char *file
, int line
)
582 struct binding_value
*bv
= *v
;
584 *v
= (struct binding_value
*)0;
586 /* Decrement the reference count. If it's nonzero, we're
589 rc_register (file
, line
, v
, bv
, bv
-> refcnt
, 1, RC_MISC
);
590 if (bv
-> refcnt
> 0)
592 if (bv
-> refcnt
< 0) {
593 log_error ("%s(%d): negative refcnt!", file
, line
);
594 #if defined (DEBUG_RC_HISTORY)
595 dump_rc_history (bv
);
597 #if defined (POINTER_DEBUG)
604 switch (bv
-> type
) {
605 case binding_boolean
:
606 case binding_numeric
:
609 if (bv
-> value
.data
.buffer
)
610 data_string_forget (&bv
-> value
.data
, file
, line
);
613 #if defined (NSUPDATE)
614 if (bv
-> value
.dns
) {
615 if (bv
-> value
.dns
-> r_data
) {
616 dfree (bv
-> value
.dns
-> r_data_ephem
, MDL
);
617 bv
-> value
.dns
-> r_data
= (unsigned char *)0;
618 bv
-> value
.dns
-> r_data_ephem
=
621 minires_freeupdrec (bv
-> value
.dns
);
626 log_error ("%s(%d): invalid binding type: %d",
627 file
, line
, bv
-> type
);
630 dfree (bv
, file
, line
);
634 #if defined (NSUPDATE)
635 int evaluate_dns_expression (result
, packet
, lease
, client_state
, in_options
,
636 cfg_options
, scope
, expr
)
638 struct packet
*packet
;
640 struct client_state
*client_state
;
641 struct option_state
*in_options
;
642 struct option_state
*cfg_options
;
643 struct binding_scope
**scope
;
644 struct expression
*expr
;
646 unsigned long ttl
= 0;
648 struct data_string name
, data
;
651 tname
= NULL
; /* XXXGCC -Wuninitialized */
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
;
909 struct binding
*binding
;
910 struct binding_value
*bv
, *obv
;
912 switch (expr
-> op
) {
914 *result
= check_collection (packet
, lease
,
916 #if defined (DEBUG_EXPRESSIONS)
917 log_debug ("bool: check (%s) returns %s",
918 expr
-> data
.check
-> name
,
919 *result
? "true" : "false");
925 bv
= obv
= (struct binding_value
*)0;
926 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
927 in_options
, cfg_options
, scope
,
928 expr
-> data
.equal
[0], MDL
);
929 sright
= evaluate_expression (&obv
, packet
, lease
,
930 client_state
, in_options
,
932 expr
-> data
.equal
[1], MDL
);
933 if (sleft
&& sright
) {
934 if (bv
-> type
!= obv
-> type
)
935 *result
= expr
-> op
== expr_not_equal
;
937 switch (obv
-> type
) {
938 case binding_boolean
:
939 if (bv
-> value
.boolean
== obv
-> value
.boolean
)
940 *result
= expr
-> op
== expr_equal
;
942 *result
= expr
-> op
== expr_not_equal
;
946 if ((bv
-> value
.data
.len
==
947 obv
-> value
.data
.len
) &&
948 !memcmp (bv
-> value
.data
.data
,
949 obv
-> value
.data
.data
,
950 obv
-> value
.data
.len
))
951 *result
= expr
-> op
== expr_equal
;
953 *result
= expr
-> op
== expr_not_equal
;
956 case binding_numeric
:
957 if (bv
-> value
.intval
== obv
-> value
.intval
)
958 *result
= expr
-> op
== expr_equal
;
960 *result
= expr
-> op
== expr_not_equal
;
964 #if defined (NSUPDATE)
965 /* XXX This should be a comparison for equal
966 XXX values, not for identity. */
967 if (bv
-> value
.dns
== obv
-> value
.dns
)
968 *result
= expr
-> op
== expr_equal
;
970 *result
= expr
-> op
== expr_not_equal
;
972 *result
= expr
-> op
== expr_not_equal
;
976 case binding_function
:
977 if (bv
-> value
.fundef
== obv
-> value
.fundef
)
978 *result
= expr
-> op
== expr_equal
;
980 *result
= expr
-> op
== expr_not_equal
;
983 *result
= expr
-> op
== expr_not_equal
;
987 } else if (!sleft
&& !sright
)
988 *result
= expr
-> op
== expr_equal
;
990 *result
= expr
-> op
== expr_not_equal
;
992 #if defined (DEBUG_EXPRESSIONS)
993 log_debug ("bool: %sequal = %s",
994 expr
-> op
== expr_not_equal
? "not" : "",
995 (*result
? "true" : "false"));
998 binding_value_dereference (&bv
, MDL
);
1000 binding_value_dereference (&obv
, MDL
);
1004 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1006 in_options
, cfg_options
,
1008 expr
-> data
.and [0]);
1010 sright
= evaluate_boolean_expression
1011 (&bright
, packet
, lease
, client_state
,
1012 in_options
, cfg_options
,
1013 scope
, expr
-> data
.and [1]);
1015 sright
= bright
= 0;
1017 #if defined (DEBUG_EXPRESSIONS)
1018 log_debug ("bool: and (%s, %s) = %s",
1019 sleft
? (bleft
? "true" : "false") : "NULL",
1020 sright
? (bright
? "true" : "false") : "NULL",
1022 ? (bleft
&& bright
? "true" : "false") : "NULL"));
1024 if (sleft
&& sright
) {
1025 *result
= bleft
&& bright
;
1032 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1034 in_options
, cfg_options
,
1036 expr
-> data
.or [0]);
1037 if (!sleft
|| !bleft
)
1038 sright
= evaluate_boolean_expression
1039 (&bright
, packet
, lease
, client_state
,
1040 in_options
, cfg_options
,
1041 scope
, expr
-> data
.or [1]);
1044 #if defined (DEBUG_EXPRESSIONS)
1045 log_debug ("bool: or (%s, %s) = %s",
1046 sleft
? (bleft
? "true" : "false") : "NULL",
1047 sright
? (bright
? "true" : "false") : "NULL",
1049 ? (bleft
|| bright
? "true" : "false") : "NULL"));
1051 if (sleft
|| sright
) {
1052 *result
= bleft
|| bright
;
1058 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1060 in_options
, cfg_options
,
1063 #if defined (DEBUG_EXPRESSIONS)
1064 log_debug ("bool: not (%s) = %s",
1065 sleft
? (bleft
? "true" : "false") : "NULL",
1067 ? (!bleft
? "true" : "false") : "NULL"));
1077 memset (&left
, 0, sizeof left
);
1079 !get_option (&left
, expr
-> data
.exists
-> universe
,
1080 packet
, lease
, client_state
,
1081 in_options
, cfg_options
, in_options
,
1082 scope
, expr
-> data
.exists
-> code
, MDL
))
1086 data_string_forget (&left
, MDL
);
1088 #if defined (DEBUG_EXPRESSIONS)
1089 log_debug ("bool: exists %s.%s = %s",
1090 expr
-> data
.option
-> universe
-> name
,
1091 expr
-> data
.option
-> name
,
1092 *result
? "true" : "false");
1098 #if defined (DEBUG_EXPRESSIONS)
1099 log_debug ("bool: known = NULL");
1103 #if defined (DEBUG_EXPRESSIONS)
1104 log_debug ("bool: known = %s",
1105 packet
-> known
? "true" : "false");
1107 *result
= packet
-> known
;
1111 if (!lease
|| !(lease
-> flags
& STATIC_LEASE
)) {
1112 #if defined (DEBUG_EXPRESSIONS)
1113 log_debug ("bool: static = false (%s %s %s %d)",
1115 (lease
&& (lease
-> flags
& STATIC_LEASE
)
1117 piaddr (lease
-> ip_addr
),
1118 lease
? lease
-> flags
: 0);
1123 #if defined (DEBUG_EXPRESSIONS)
1124 log_debug ("bool: static = true");
1129 case expr_variable_exists
:
1130 if (scope
&& *scope
) {
1131 binding
= find_binding (*scope
, expr
-> data
.variable
);
1134 if (binding
-> value
)
1142 #if defined (DEBUG_EXPRESSIONS)
1143 log_debug ("boolean: %s? = %s", expr
-> data
.variable
,
1144 *result
? "true" : "false");
1148 case expr_variable_reference
:
1149 if (scope
&& *scope
) {
1150 binding
= find_binding (*scope
, expr
-> data
.variable
);
1152 if (binding
&& binding
-> value
) {
1153 if (binding
-> value
-> type
==
1155 *result
= binding
-> value
-> value
.boolean
;
1158 log_error ("binding type %d in %s.",
1159 binding
-> value
-> type
,
1160 "evaluate_boolean_expression");
1167 #if defined (DEBUG_EXPRESSIONS)
1168 log_debug ("boolean: %s = %s", expr
-> data
.variable
,
1169 sleft
? (*result
? "true" : "false") : "NULL");
1174 bv
= (struct binding_value
*)0;
1175 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1176 in_options
, cfg_options
,
1179 if (bv
-> type
!= binding_boolean
)
1180 log_error ("%s() returned type %d in %s.",
1181 expr
-> data
.funcall
.name
,
1183 "evaluate_boolean_expression");
1185 *result
= bv
-> value
.boolean
;
1186 binding_value_dereference (&bv
, MDL
);
1188 #if defined (DEBUG_EXPRESSIONS)
1189 log_debug ("boolean: %s() = %s", expr
-> data
.funcall
.name
,
1190 sleft
? (*result
? "true" : "false") : "NULL");
1196 case expr_substring
:
1200 case expr_const_data
:
1203 case expr_encapsulate
:
1204 case expr_host_lookup
:
1205 case expr_encode_int8
:
1206 case expr_encode_int16
:
1207 case expr_encode_int32
:
1208 case expr_binary_to_ascii
:
1210 case expr_pick_first_value
:
1211 case expr_host_decl_name
:
1212 case expr_config_option
:
1213 case expr_leased_address
:
1217 log_error ("Data opcode in evaluate_boolean_expression: %d",
1221 case expr_extract_int8
:
1222 case expr_extract_int16
:
1223 case expr_extract_int32
:
1224 case expr_const_int
:
1225 case expr_lease_time
:
1226 case expr_dns_transaction
:
1231 case expr_remainder
:
1232 case expr_binary_and
:
1233 case expr_binary_or
:
1234 case expr_binary_xor
:
1235 case expr_client_state
:
1236 log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1241 case expr_ns_delete
:
1242 case expr_ns_exists
:
1243 case expr_ns_not_exists
:
1244 log_error ("dns opcode in evaluate_boolean_expression: %d",
1249 log_error ("function definition in evaluate_boolean_expr");
1256 log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1261 int evaluate_data_expression (result
, packet
, lease
, client_state
,
1262 in_options
, cfg_options
, scope
, expr
, file
, line
)
1263 struct data_string
*result
;
1264 struct packet
*packet
;
1265 struct lease
*lease
;
1266 struct client_state
*client_state
;
1267 struct option_state
*in_options
;
1268 struct option_state
*cfg_options
;
1269 struct binding_scope
**scope
;
1270 struct expression
*expr
;
1274 struct data_string data
, other
;
1275 unsigned long offset
, len
;
1278 struct binding
*binding
;
1279 struct binding_value
*bv
;
1281 status
= 0; /* XXXGCC -Wuninitialized */
1283 switch (expr
-> op
) {
1284 /* Extract N bytes starting at byte M of a data string. */
1285 case expr_substring
:
1286 memset (&data
, 0, sizeof data
);
1287 s0
= evaluate_data_expression (&data
, packet
, lease
,
1289 in_options
, cfg_options
, scope
,
1290 expr
-> data
.substring
.expr
,
1293 /* Evaluate the offset and length. */
1294 s1
= evaluate_numeric_expression
1295 (&offset
, packet
, lease
, client_state
, in_options
,
1296 cfg_options
, scope
, expr
-> data
.substring
.offset
);
1297 s2
= evaluate_numeric_expression (&len
, packet
, lease
,
1299 in_options
, cfg_options
,
1301 expr
-> data
.substring
.len
);
1303 if (s0
&& s1
&& s2
) {
1304 /* If the offset is after end of the string,
1305 return an empty string. Otherwise, do the
1306 adjustments and return what's left. */
1307 if (data
.len
> offset
) {
1308 data_string_copy (result
, &data
, file
, line
);
1309 result
-> len
-= offset
;
1310 if (result
-> len
> len
) {
1311 result
-> len
= len
;
1312 result
-> terminated
= 0;
1314 result
-> data
+= offset
;
1320 #if defined (DEBUG_EXPRESSIONS)
1321 log_debug ("data: substring (%s, %s, %s) = %s",
1322 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1323 s1
? print_dec_1 (offset
) : "NULL",
1324 s2
? print_dec_2 (len
) : "NULL",
1325 (s3
? print_hex_2 (result
-> len
, result
-> data
, 30)
1329 data_string_forget (&data
, MDL
);
1335 /* Extract the last N bytes of a data string. */
1337 memset (&data
, 0, sizeof data
);
1338 s0
= evaluate_data_expression (&data
, packet
, lease
,
1340 in_options
, cfg_options
, scope
,
1341 expr
-> data
.suffix
.expr
, MDL
);
1342 /* Evaluate the length. */
1343 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1345 in_options
, cfg_options
,
1347 expr
-> data
.suffix
.len
);
1349 data_string_copy (result
, &data
, file
, line
);
1351 /* If we are returning the last N bytes of a
1352 string whose length is <= N, just return
1353 the string - otherwise, compute a new
1354 starting address and decrease the
1356 if (data
.len
> len
) {
1357 result
-> data
+= data
.len
- len
;
1358 result
-> len
= len
;
1360 data_string_forget (&data
, MDL
);
1363 #if defined (DEBUG_EXPRESSIONS)
1364 log_debug ("data: suffix (%s, %s) = %s",
1365 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1366 s1
? print_dec_1 (len
) : "NULL",
1368 ? print_hex_2 (result
-> len
, result
-> data
, 30)
1373 /* Extract an option. */
1376 s0
= get_option (result
,
1377 expr
-> data
.option
-> universe
,
1378 packet
, lease
, client_state
,
1379 in_options
, cfg_options
, in_options
,
1380 scope
, expr
-> data
.option
-> code
,
1385 #if defined (DEBUG_EXPRESSIONS)
1386 log_debug ("data: option %s.%s = %s",
1387 expr
-> data
.option
-> universe
-> name
,
1388 expr
-> data
.option
-> name
,
1389 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1394 case expr_config_option
:
1396 s0
= get_option (result
,
1397 expr
-> data
.option
-> universe
,
1398 packet
, lease
, client_state
,
1399 in_options
, cfg_options
, cfg_options
,
1400 scope
, expr
-> data
.option
-> code
,
1405 #if defined (DEBUG_EXPRESSIONS)
1406 log_debug ("data: config-option %s.%s = %s",
1407 expr
-> data
.option
-> universe
-> name
,
1408 expr
-> data
.option
-> name
,
1409 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1414 /* Combine the hardware type and address. */
1416 /* On the client, hardware is our hardware. */
1418 memset (result
, 0, sizeof *result
);
1420 client_state
-> interface
-> hw_address
.hbuf
;
1422 client_state
-> interface
-> hw_address
.hlen
;
1423 #if defined (DEBUG_EXPRESSIONS)
1424 log_debug ("data: hardware = %s",
1425 print_hex_1 (result
-> len
,
1426 result
-> data
, 60));
1431 /* The server cares about the client's hardware address,
1432 so only in the case where we are examining a packet can
1433 we return anything. */
1434 if (!packet
|| !packet
-> raw
) {
1435 log_error ("data: hardware: raw packet not available");
1438 if (packet
-> raw
-> hlen
> sizeof packet
-> raw
-> chaddr
) {
1439 log_error ("data: hardware: invalid hlen (%d)\n",
1440 packet
-> raw
-> hlen
);
1443 result
-> len
= packet
-> raw
-> hlen
+ 1;
1444 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1446 result
-> data
= &result
-> buffer
-> data
[0];
1447 result
-> buffer
-> data
[0] = packet
-> raw
-> htype
;
1448 memcpy (&result
-> buffer
-> data
[1],
1449 packet
-> raw
-> chaddr
,
1450 packet
-> raw
-> hlen
);
1451 result
-> terminated
= 0;
1453 log_error ("data: hardware: no memory for buffer.");
1456 #if defined (DEBUG_EXPRESSIONS)
1457 log_debug ("data: hardware = %s",
1458 print_hex_1 (result
-> len
, result
-> data
, 60));
1462 /* Extract part of the raw packet. */
1464 if (!packet
|| !packet
-> raw
) {
1465 log_error ("data: packet: raw packet not available");
1469 s0
= evaluate_numeric_expression (&offset
, packet
, lease
,
1471 in_options
, cfg_options
,
1473 expr
-> data
.packet
.offset
);
1474 s1
= evaluate_numeric_expression (&len
,
1475 packet
, lease
, client_state
,
1476 in_options
, cfg_options
,
1478 expr
-> data
.packet
.len
);
1479 if (s0
&& s1
&& offset
< packet
-> packet_length
) {
1480 if (offset
+ len
> packet
-> packet_length
)
1482 packet
-> packet_length
- offset
;
1484 result
-> len
= len
;
1485 if (buffer_allocate (&result
-> buffer
,
1486 result
-> len
, file
, line
)) {
1487 result
-> data
= &result
-> buffer
-> data
[0];
1488 memcpy (result
-> buffer
-> data
,
1489 (((unsigned char *)(packet
-> raw
))
1490 + offset
), result
-> len
);
1491 result
-> terminated
= 0;
1493 log_error ("data: packet: no buffer memory.");
1499 #if defined (DEBUG_EXPRESSIONS)
1500 log_debug ("data: packet (%ld, %ld) = %s",
1502 s2
? print_hex_1 (result
-> len
,
1503 result
-> data
, 60) : NULL
);
1507 /* The encapsulation of all defined options in an
1509 case expr_encapsulate
:
1511 s0
= option_space_encapsulate
1512 (result
, packet
, lease
, client_state
,
1513 in_options
, cfg_options
, scope
,
1514 &expr
-> data
.encapsulate
);
1518 #if defined (DEBUG_EXPRESSIONS)
1519 log_debug ("data: encapsulate (%s) = %s",
1520 expr
-> data
.encapsulate
.data
,
1521 s0
? print_hex_1 (result
-> len
,
1522 result
-> data
, 60) : "NULL");
1526 /* Some constant data... */
1527 case expr_const_data
:
1528 #if defined (DEBUG_EXPRESSIONS)
1529 log_debug ("data: const = %s",
1530 print_hex_1 (expr
-> data
.const_data
.len
,
1531 expr
-> data
.const_data
.data
, 60));
1533 data_string_copy (result
,
1534 &expr
-> data
.const_data
, file
, line
);
1537 /* Hostname lookup... */
1538 case expr_host_lookup
:
1539 s0
= do_host_lookup (result
, expr
-> data
.host_lookup
);
1540 #if defined (DEBUG_EXPRESSIONS)
1541 log_debug ("data: DNS lookup (%s) = %s",
1542 expr
-> data
.host_lookup
-> hostname
,
1544 ? print_dotted_quads (result
-> len
, result
-> data
)
1549 /* Concatenation... */
1551 memset (&data
, 0, sizeof data
);
1552 s0
= evaluate_data_expression (&data
, packet
, lease
,
1554 in_options
, cfg_options
, scope
,
1555 expr
-> data
.concat
[0], MDL
);
1556 memset (&other
, 0, sizeof other
);
1557 s1
= evaluate_data_expression (&other
, packet
, lease
,
1559 in_options
, cfg_options
, scope
,
1560 expr
-> data
.concat
[1], MDL
);
1563 result
-> len
= data
.len
+ other
.len
;
1564 if (!buffer_allocate (&result
-> buffer
,
1565 (result
-> len
+ other
.terminated
),
1567 log_error ("data: concat: no memory");
1569 data_string_forget (&data
, MDL
);
1570 data_string_forget (&other
, MDL
);
1573 result
-> data
= &result
-> buffer
-> data
[0];
1574 memcpy (result
-> buffer
-> data
, data
.data
, data
.len
);
1575 memcpy (&result
-> buffer
-> data
[data
.len
],
1576 other
.data
, other
.len
+ other
.terminated
);
1580 data_string_forget (&data
, MDL
);
1582 data_string_forget (&other
, MDL
);
1583 #if defined (DEBUG_EXPRESSIONS)
1584 log_debug ("data: concat (%s, %s) = %s",
1585 s0
? print_hex_1 (data
.len
, data
.data
, 20) : "NULL",
1586 s1
? print_hex_2 (other
.len
, other
.data
, 20) : "NULL",
1588 ? print_hex_3 (result
-> len
, result
-> data
, 30)
1593 case expr_encode_int8
:
1594 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1596 in_options
, cfg_options
,
1598 expr
-> data
.encode_int
);
1601 if (!buffer_allocate (&result
-> buffer
,
1603 log_error ("data: encode_int8: no memory");
1607 result
-> data
= &result
-> buffer
-> data
[0];
1608 result
-> buffer
-> data
[0] = len
;
1613 #if defined (DEBUG_EXPRESSIONS)
1615 log_debug ("data: encode_int8 (NULL) = NULL");
1617 log_debug ("data: encode_int8 (%ld) = %s", len
,
1618 print_hex_2 (result
-> len
,
1619 result
-> data
, 20));
1624 case expr_encode_int16
:
1625 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1627 in_options
, cfg_options
,
1629 expr
-> data
.encode_int
);
1632 if (!buffer_allocate (&result
-> buffer
, 2,
1634 log_error ("data: encode_int16: no memory");
1638 result
-> data
= &result
-> buffer
-> data
[0];
1639 putUShort (result
-> buffer
-> data
, len
);
1644 #if defined (DEBUG_EXPRESSIONS)
1646 log_debug ("data: encode_int16 (NULL) = NULL");
1648 log_debug ("data: encode_int16 (%ld) = %s", len
,
1649 print_hex_2 (result
-> len
,
1650 result
-> data
, 20));
1654 case expr_encode_int32
:
1655 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1657 in_options
, cfg_options
,
1659 expr
-> data
.encode_int
);
1662 if (!buffer_allocate (&result
-> buffer
, 4,
1664 log_error ("data: encode_int32: no memory");
1668 result
-> data
= &result
-> buffer
-> data
[0];
1669 putULong (result
-> buffer
-> data
, len
);
1674 #if defined (DEBUG_EXPRESSIONS)
1676 log_debug ("data: encode_int32 (NULL) = NULL");
1678 log_debug ("data: encode_int32 (%ld) = %s", len
,
1679 print_hex_2 (result
-> len
,
1680 result
-> data
, 20));
1684 case expr_binary_to_ascii
:
1685 /* Evaluate the base (offset) and width (len): */
1686 s0
= evaluate_numeric_expression
1687 (&offset
, packet
, lease
, client_state
, in_options
,
1688 cfg_options
, scope
, expr
-> data
.b2a
.base
);
1689 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1691 in_options
, cfg_options
,
1693 expr
-> data
.b2a
.width
);
1695 /* Evaluate the seperator string. */
1696 memset (&data
, 0, sizeof data
);
1697 s2
= evaluate_data_expression (&data
, packet
, lease
,
1699 in_options
, cfg_options
, scope
,
1700 expr
-> data
.b2a
.seperator
,
1703 /* Evaluate the data to be converted. */
1704 memset (&other
, 0, sizeof other
);
1705 s3
= evaluate_data_expression (&other
, packet
, lease
,
1707 in_options
, cfg_options
, scope
,
1708 expr
-> data
.b2a
.buffer
, MDL
);
1710 if (s0
&& s1
&& s2
&& s3
) {
1713 if (len
!= 8 && len
!= 16 && len
!= 32) {
1714 log_info ("binary_to_ascii: %s %ld!",
1715 "invalid width", len
);
1721 /* The buffer must be a multiple of the number's
1723 if (other
.len
% len
) {
1724 log_info ("binary-to-ascii: %s %d %s %ld!",
1725 "length of buffer", other
.len
,
1726 "not a multiple of width", len
);
1731 /* Count the width of the output. */
1733 for (i
= 0; i
< other
.len
; i
+= len
) {
1736 if (other
.data
[i
] < 8)
1738 else if (other
.data
[i
] < 64)
1742 } else if (offset
== 10) {
1743 if (other
.data
[i
] < 10)
1745 else if (other
.data
[i
] < 100)
1749 } else if (offset
== 16) {
1750 if (other
.data
[i
] < 16)
1755 buflen
+= (converted_length
1759 buflen
+= (converted_length
1762 if (i
+ len
!= other
.len
)
1766 if (!buffer_allocate (&result
-> buffer
,
1767 buflen
+ 1, file
, line
)) {
1768 log_error ("data: binary-to-ascii: no memory");
1772 result
-> data
= &result
-> buffer
-> data
[0];
1773 result
-> len
= buflen
;
1774 result
-> terminated
= 1;
1777 for (i
= 0; i
< other
.len
; i
+= len
) {
1778 buflen
+= (binary_to_ascii
1779 (&result
-> buffer
-> data
[buflen
],
1780 &other
.data
[i
], offset
, len
));
1781 if (i
+ len
!= other
.len
) {
1783 buffer
-> data
[buflen
],
1784 data
.data
, data
.len
);
1788 /* NUL terminate. */
1789 result
-> buffer
-> data
[buflen
] = 0;
1795 #if defined (DEBUG_EXPRESSIONS)
1796 log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
1797 s0
? print_dec_1 (offset
) : "NULL",
1798 s1
? print_dec_2 (len
) : "NULL",
1799 s2
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1800 s3
? print_hex_2 (other
.len
, other
.data
, 30) : "NULL",
1801 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1805 data_string_forget (&data
, MDL
);
1807 data_string_forget (&other
, MDL
);
1813 /* Evaluate the width (len): */
1814 s0
= evaluate_numeric_expression
1815 (&len
, packet
, lease
, client_state
, in_options
,
1816 cfg_options
, scope
, expr
-> data
.reverse
.width
);
1818 /* Evaluate the data. */
1819 memset (&data
, 0, sizeof data
);
1820 s1
= evaluate_data_expression (&data
, packet
, lease
,
1822 in_options
, cfg_options
, scope
,
1823 expr
-> data
.reverse
.buffer
,
1829 /* The buffer must be a multiple of the number's
1831 if (data
.len
% len
) {
1832 log_info ("reverse: %s %d %s %ld!",
1833 "length of buffer", data
.len
,
1834 "not a multiple of width", len
);
1839 /* XXX reverse in place? I don't think we can. */
1840 if (!buffer_allocate (&result
-> buffer
,
1841 data
.len
, file
, line
)) {
1842 log_error ("data: reverse: no memory");
1846 result
-> data
= &result
-> buffer
-> data
[0];
1847 result
-> len
= data
.len
;
1848 result
-> terminated
= 0;
1850 for (i
= 0; i
< data
.len
; i
+= len
) {
1851 memcpy (&result
-> buffer
-> data
[i
],
1852 &data
.data
[data
.len
- i
- len
], len
);
1859 #if defined (DEBUG_EXPRESSIONS)
1860 log_debug ("data: reverse (%s, %s) = %s",
1861 s0
? print_dec_1 (len
) : "NULL",
1862 s1
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1863 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1867 data_string_forget (&data
, MDL
);
1872 case expr_leased_address
:
1874 log_error ("data: leased_address: not available");
1877 result
-> len
= lease
-> ip_addr
.len
;
1878 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1880 result
-> data
= &result
-> buffer
-> data
[0];
1881 memcpy (&result
-> buffer
-> data
[0],
1882 lease
-> ip_addr
.iabuf
, lease
-> ip_addr
.len
);
1883 result
-> terminated
= 0;
1885 log_error ("data: leased-address: no memory.");
1888 #if defined (DEBUG_EXPRESSIONS)
1889 log_debug ("data: leased-address = %s",
1890 print_hex_1 (result
-> len
, result
-> data
, 60));
1894 case expr_pick_first_value
:
1895 memset (&data
, 0, sizeof data
);
1896 if ((evaluate_data_expression
1898 lease
, client_state
, in_options
, cfg_options
,
1899 scope
, expr
-> data
.pick_first_value
.car
, MDL
))) {
1900 #if defined (DEBUG_EXPRESSIONS)
1901 log_debug ("data: pick_first_value (%s, xxx)",
1902 print_hex_1 (result
-> len
,
1903 result
-> data
, 40));
1908 if (expr
-> data
.pick_first_value
.cdr
&&
1909 (evaluate_data_expression
1911 lease
, client_state
, in_options
, cfg_options
,
1912 scope
, expr
-> data
.pick_first_value
.cdr
, MDL
))) {
1913 #if defined (DEBUG_EXPRESSIONS)
1914 log_debug ("data: pick_first_value (NULL, %s)",
1915 print_hex_1 (result
-> len
,
1916 result
-> data
, 40));
1921 #if defined (DEBUG_EXPRESSIONS)
1922 log_debug ("data: pick_first_value (NULL, NULL) = NULL");
1926 case expr_host_decl_name
:
1927 if (!lease
|| !lease
-> host
) {
1928 log_error ("data: host_decl_name: not available");
1931 result
-> len
= strlen (lease
-> host
-> name
);
1932 if (buffer_allocate (&result
-> buffer
,
1933 result
-> len
+ 1, file
, line
)) {
1934 result
-> data
= &result
-> buffer
-> data
[0];
1935 strcpy ((char *)&result
-> buffer
-> data
[0],
1936 lease
-> host
-> name
);
1937 result
-> terminated
= 1;
1939 log_error ("data: host-decl-name: no memory.");
1942 #if defined (DEBUG_EXPRESSIONS)
1943 log_debug ("data: host-decl-name = %s", lease
-> host
-> name
);
1948 #if defined (DEBUG_EXPRESSIONS)
1949 log_debug ("data: null = NULL");
1953 case expr_variable_reference
:
1954 if (scope
&& *scope
) {
1955 binding
= find_binding (*scope
, expr
-> data
.variable
);
1957 if (binding
&& binding
-> value
) {
1958 if (binding
-> value
-> type
== binding_data
) {
1959 data_string_copy (result
,
1960 &binding
-> value
-> value
.data
,
1963 } else if (binding
-> value
-> type
!= binding_data
) {
1964 log_error ("binding type %d in %s.",
1965 binding
-> value
-> type
,
1966 "evaluate_data_expression");
1974 #if defined (DEBUG_EXPRESSIONS)
1975 log_debug ("data: %s = %s", expr
-> data
.variable
,
1976 s0
? print_hex_1 (result
-> len
,
1977 result
-> data
, 50) : "NULL");
1982 bv
= (struct binding_value
*)0;
1983 s0
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1984 in_options
, cfg_options
,
1987 if (bv
-> type
!= binding_data
)
1988 log_error ("%s() returned type %d in %s.",
1989 expr
-> data
.funcall
.name
,
1991 "evaluate_data_expression");
1993 data_string_copy (result
, &bv
-> value
.data
,
1995 binding_value_dereference (&bv
, MDL
);
1997 #if defined (DEBUG_EXPRESSIONS)
1998 log_debug ("data: %s = %s", expr
-> data
.funcall
.name
,
1999 s0
? print_hex_1 (result
-> len
,
2000 result
-> data
, 50) : "NULL");
2004 /* Extract the filename. */
2006 if (packet
&& packet
-> raw
-> file
[0]) {
2008 memchr (packet
-> raw
-> file
, 0,
2009 sizeof packet
-> raw
-> file
);
2011 fn
= ((char *)packet
-> raw
-> file
+
2012 sizeof packet
-> raw
-> file
);
2013 result
-> len
= fn
- &(packet
-> raw
-> file
[0]);
2014 if (buffer_allocate (&result
-> buffer
,
2015 result
-> len
+ 1, file
, line
)) {
2016 result
-> data
= &result
-> buffer
-> data
[0];
2017 memcpy (&result
-> buffer
-> data
[0],
2018 packet
-> raw
-> file
,
2020 result
-> buffer
-> data
[result
-> len
] = 0;
2021 result
-> terminated
= 1;
2024 log_error ("data: filename: no memory.");
2030 #if defined (DEBUG_EXPRESSIONS)
2031 log_info ("data: filename = \"%s\"",
2032 s0
? (const char *)(result
-> data
) : "NULL");
2036 /* Extract the server name. */
2038 if (packet
&& packet
-> raw
-> sname
[0]) {
2040 memchr (packet
-> raw
-> sname
, 0,
2041 sizeof packet
-> raw
-> sname
);
2043 fn
= ((char *)packet
-> raw
-> sname
+
2044 sizeof packet
-> raw
-> sname
);
2045 result
-> len
= fn
- &packet
-> raw
-> sname
[0];
2046 if (buffer_allocate (&result
-> buffer
,
2047 result
-> len
+ 1, file
, line
)) {
2048 result
-> data
= &result
-> buffer
-> data
[0];
2049 memcpy (&result
-> buffer
-> data
[0],
2050 packet
-> raw
-> sname
,
2052 result
-> buffer
-> data
[result
-> len
] = 0;
2053 result
-> terminated
= 1;
2056 log_error ("data: sname: no memory.");
2062 #if defined (DEBUG_EXPRESSIONS)
2063 log_info ("data: sname = \"%s\"",
2064 s0
? (const char *)(result
-> data
) : "NULL");
2070 case expr_not_equal
:
2079 case expr_variable_exists
:
2080 log_error ("Boolean opcode in evaluate_data_expression: %d",
2084 case expr_extract_int8
:
2085 case expr_extract_int16
:
2086 case expr_extract_int32
:
2087 case expr_const_int
:
2088 case expr_lease_time
:
2089 case expr_dns_transaction
:
2094 case expr_remainder
:
2095 case expr_binary_and
:
2096 case expr_binary_or
:
2097 case expr_binary_xor
:
2098 case expr_client_state
:
2099 log_error ("Numeric opcode in evaluate_data_expression: %d",
2104 case expr_ns_delete
:
2105 case expr_ns_exists
:
2106 case expr_ns_not_exists
:
2107 log_error ("dns update opcode in evaluate_data_expression: %d",
2112 log_error ("function definition in evaluate_data_expression");
2119 log_error ("Bogus opcode in evaluate_data_expression: %d", expr
-> op
);
2123 int evaluate_numeric_expression (result
, packet
, lease
, client_state
,
2124 in_options
, cfg_options
, scope
, expr
)
2125 unsigned long *result
;
2126 struct packet
*packet
;
2127 struct lease
*lease
;
2128 struct client_state
*client_state
;
2129 struct option_state
*in_options
;
2130 struct option_state
*cfg_options
;
2131 struct binding_scope
**scope
;
2132 struct expression
*expr
;
2134 struct data_string data
;
2135 int status
, sleft
, sright
;
2136 #if defined (NSUPDATE)
2140 struct expression
*cur
, *next
;
2141 struct binding
*binding
;
2142 struct binding_value
*bv
;
2143 unsigned long ileft
, iright
;
2145 switch (expr
-> op
) {
2148 case expr_not_equal
:
2157 case expr_variable_exists
:
2158 log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2162 case expr_substring
:
2166 case expr_const_data
:
2169 case expr_encapsulate
:
2170 case expr_host_lookup
:
2171 case expr_encode_int8
:
2172 case expr_encode_int16
:
2173 case expr_encode_int32
:
2174 case expr_binary_to_ascii
:
2178 case expr_pick_first_value
:
2179 case expr_host_decl_name
:
2180 case expr_config_option
:
2181 case expr_leased_address
:
2183 log_error ("Data opcode in evaluate_numeric_expression: %d",
2187 case expr_extract_int8
:
2188 memset (&data
, 0, sizeof data
);
2189 status
= evaluate_data_expression
2190 (&data
, packet
, lease
, client_state
, in_options
,
2191 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
);
2193 *result
= data
.data
[0];
2194 #if defined (DEBUG_EXPRESSIONS)
2195 log_debug ("num: extract_int8 (%s) = %s",
2196 status
? print_hex_1 (data
.len
, data
.data
, 60) : "NULL",
2197 status
? print_dec_1 (*result
) : "NULL" );
2199 if (status
) data_string_forget (&data
, MDL
);
2202 case expr_extract_int16
:
2203 memset (&data
, 0, sizeof data
);
2204 status
= (evaluate_data_expression
2205 (&data
, packet
, lease
, client_state
, in_options
,
2206 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2207 if (status
&& data
.len
>= 2)
2208 *result
= getUShort (data
.data
);
2209 #if defined (DEBUG_EXPRESSIONS)
2210 log_debug ("num: extract_int16 (%s) = %ld",
2211 ((status
&& data
.len
>= 2) ?
2212 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2215 if (status
) data_string_forget (&data
, MDL
);
2216 return (status
&& data
.len
>= 2);
2218 case expr_extract_int32
:
2219 memset (&data
, 0, sizeof data
);
2220 status
= (evaluate_data_expression
2221 (&data
, packet
, lease
, client_state
, in_options
,
2222 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2223 if (status
&& data
.len
>= 4)
2224 *result
= getULong (data
.data
);
2225 #if defined (DEBUG_EXPRESSIONS)
2226 log_debug ("num: extract_int32 (%s) = %ld",
2227 ((status
&& data
.len
>= 4) ?
2228 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2231 if (status
) data_string_forget (&data
, MDL
);
2232 return (status
&& data
.len
>= 4);
2234 case expr_const_int
:
2235 *result
= expr
-> data
.const_int
;
2236 #if defined (DEBUG_EXPRESSIONS)
2237 log_debug ("number: CONSTANT = %ld", *result
);
2241 case expr_lease_time
:
2243 log_error ("data: leased_lease: not available");
2246 if (lease
-> ends
< cur_time
) {
2247 log_error ("%s %lu when it is now %lu",
2248 "data: lease_time: lease ends at",
2249 (long)(lease
-> ends
), (long)cur_time
);
2252 *result
= lease
-> ends
- cur_time
;
2253 #if defined (DEBUG_EXPRESSIONS)
2254 log_debug ("number: lease-time = (%lu - %lu) = %ld",
2260 case expr_dns_transaction
:
2261 #if !defined (NSUPDATE)
2264 if (!resolver_inited
) {
2265 minires_ninit (&resolver_state
);
2266 resolver_inited
= 1;
2267 resolver_state
.retrans
= 1;
2268 resolver_state
.retry
= 1;
2273 next
= cur
-> data
.dns_transaction
.cdr
;
2275 status
= (evaluate_dns_expression
2277 lease
, client_state
, in_options
, cfg_options
,
2278 scope
, cur
-> data
.dns_transaction
.car
));
2281 ISC_LIST_APPEND (uq
, nut
, r_link
);
2285 /* Do the update and record the error code, if there was
2286 an error; otherwise set it to NOERROR. */
2287 *result
= minires_nupdate (&resolver_state
,
2288 ISC_LIST_HEAD (uq
));
2291 print_dns_status ((int)*result
, &uq
);
2294 while (!ISC_LIST_EMPTY (uq
)) {
2295 ns_updrec
*tmp
= ISC_LIST_HEAD (uq
);
2296 ISC_LIST_UNLINK (uq
, tmp
, r_link
);
2297 if (tmp
-> r_data_ephem
) {
2298 dfree (tmp
-> r_data_ephem
, MDL
);
2299 tmp
-> r_data
= (unsigned char *)0;
2300 tmp
-> r_data_ephem
= (unsigned char *)0;
2302 minires_freeupdrec (tmp
);
2305 #endif /* NSUPDATE */
2307 case expr_variable_reference
:
2308 if (scope
&& *scope
) {
2309 binding
= find_binding (*scope
, expr
-> data
.variable
);
2311 if (binding
&& binding
-> value
) {
2312 if (binding
-> value
-> type
== binding_numeric
) {
2313 *result
= binding
-> value
-> value
.intval
;
2316 log_error ("binding type %d in %s.",
2317 binding
-> value
-> type
,
2318 "evaluate_numeric_expression");
2325 #if defined (DEBUG_EXPRESSIONS)
2327 log_debug ("numeric: %s = %ld",
2328 expr
-> data
.variable
, *result
);
2330 log_debug ("numeric: %s = NULL",
2331 expr
-> data
.variable
);
2336 bv
= (struct binding_value
*)0;
2337 status
= evaluate_expression (&bv
, packet
, lease
,
2339 in_options
, cfg_options
,
2342 if (bv
-> type
!= binding_numeric
)
2343 log_error ("%s() returned type %d in %s.",
2344 expr
-> data
.funcall
.name
,
2346 "evaluate_numeric_expression");
2348 *result
= bv
-> value
.intval
;
2349 binding_value_dereference (&bv
, MDL
);
2351 #if defined (DEBUG_EXPRESSIONS)
2352 log_debug ("data: %s = %ld", expr
-> data
.funcall
.name
,
2353 status
? *result
: 0);
2358 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2360 in_options
, cfg_options
,
2362 expr
-> data
.and [0]);
2363 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2365 in_options
, cfg_options
,
2367 expr
-> data
.and [1]);
2369 #if defined (DEBUG_EXPRESSIONS)
2370 if (sleft
&& sright
)
2371 log_debug ("num: %ld + %ld = %ld",
2372 ileft
, iright
, ileft
+ iright
);
2374 log_debug ("num: %ld + NULL = NULL", ileft
);
2376 log_debug ("num: NULL + %ld = NULL", iright
);
2378 if (sleft
&& sright
) {
2379 *result
= ileft
+ iright
;
2385 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2387 in_options
, cfg_options
,
2389 expr
-> data
.and [0]);
2390 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2392 in_options
, cfg_options
,
2394 expr
-> data
.and [1]);
2396 #if defined (DEBUG_EXPRESSIONS)
2397 if (sleft
&& sright
)
2398 log_debug ("num: %ld - %ld = %ld",
2399 ileft
, iright
, ileft
- iright
);
2401 log_debug ("num: %ld - NULL = NULL", ileft
);
2403 log_debug ("num: NULL - %ld = NULL", iright
);
2405 if (sleft
&& sright
) {
2406 *result
= ileft
- iright
;
2412 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2414 in_options
, cfg_options
,
2416 expr
-> data
.and [0]);
2417 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2419 in_options
, cfg_options
,
2421 expr
-> data
.and [1]);
2423 #if defined (DEBUG_EXPRESSIONS)
2424 if (sleft
&& sright
)
2425 log_debug ("num: %ld * %ld = %ld",
2426 ileft
, iright
, ileft
* iright
);
2428 log_debug ("num: %ld * NULL = NULL", ileft
);
2430 log_debug ("num: NULL * %ld = NULL", iright
);
2432 if (sleft
&& sright
) {
2433 *result
= ileft
* iright
;
2439 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2441 in_options
, cfg_options
,
2443 expr
-> data
.and [0]);
2444 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2446 in_options
, cfg_options
,
2448 expr
-> data
.and [1]);
2450 #if defined (DEBUG_EXPRESSIONS)
2451 if (sleft
&& sright
) {
2453 log_debug ("num: %ld / %ld = %ld",
2454 ileft
, iright
, ileft
/ iright
);
2456 log_debug ("num: %ld / %ld = NULL",
2459 log_debug ("num: %ld / NULL = NULL", ileft
);
2461 log_debug ("num: NULL / %ld = NULL", iright
);
2463 if (sleft
&& sright
&& iright
) {
2464 *result
= ileft
/ iright
;
2469 case expr_remainder
:
2470 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2472 in_options
, cfg_options
,
2474 expr
-> data
.and [0]);
2475 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2477 in_options
, cfg_options
,
2479 expr
-> data
.and [1]);
2481 #if defined (DEBUG_EXPRESSIONS)
2482 if (sleft
&& sright
) {
2484 log_debug ("num: %ld %% %ld = %ld",
2485 ileft
, iright
, ileft
% iright
);
2487 log_debug ("num: %ld %% %ld = NULL",
2490 log_debug ("num: %ld %% NULL = NULL", ileft
);
2492 log_debug ("num: NULL %% %ld = NULL", iright
);
2494 if (sleft
&& sright
&& iright
) {
2495 *result
= ileft
% iright
;
2500 case expr_binary_and
:
2501 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2503 in_options
, cfg_options
,
2505 expr
-> data
.and [0]);
2506 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2508 in_options
, cfg_options
,
2510 expr
-> data
.and [1]);
2512 #if defined (DEBUG_EXPRESSIONS)
2513 if (sleft
&& sright
)
2514 log_debug ("num: %ld | %ld = %ld",
2515 ileft
, iright
, ileft
& iright
);
2517 log_debug ("num: %ld & NULL = NULL", ileft
);
2519 log_debug ("num: NULL & %ld = NULL", iright
);
2521 if (sleft
&& sright
) {
2522 *result
= ileft
& iright
;
2527 case expr_binary_or
:
2528 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2530 in_options
, cfg_options
,
2532 expr
-> data
.and [0]);
2533 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2535 in_options
, cfg_options
,
2537 expr
-> data
.and [1]);
2539 #if defined (DEBUG_EXPRESSIONS)
2540 if (sleft
&& sright
)
2541 log_debug ("num: %ld | %ld = %ld",
2542 ileft
, iright
, ileft
| iright
);
2544 log_debug ("num: %ld | NULL = NULL", ileft
);
2546 log_debug ("num: NULL | %ld = NULL", iright
);
2548 if (sleft
&& sright
) {
2549 *result
= ileft
| iright
;
2554 case expr_binary_xor
:
2555 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2557 in_options
, cfg_options
,
2559 expr
-> data
.and [0]);
2560 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2562 in_options
, cfg_options
,
2564 expr
-> data
.and [1]);
2566 #if defined (DEBUG_EXPRESSIONS)
2567 if (sleft
&& sright
)
2568 log_debug ("num: %ld ^ %ld = %ld",
2569 ileft
, iright
, ileft
^ iright
);
2571 log_debug ("num: %ld ^ NULL = NULL", ileft
);
2573 log_debug ("num: NULL ^ %ld = NULL", iright
);
2575 if (sleft
&& sright
) {
2576 *result
= ileft
^ iright
;
2581 case expr_client_state
:
2583 #if defined (DEBUG_EXPRESSIONS)
2584 log_debug ("num: client-state = %d",
2585 client_state
-> state
);
2587 *result
= client_state
-> state
;
2590 #if defined (DEBUG_EXPRESSIONS)
2591 log_debug ("num: client-state = NULL");
2597 case expr_ns_delete
:
2598 case expr_ns_exists
:
2599 case expr_ns_not_exists
:
2600 log_error ("dns opcode in evaluate_numeric_expression: %d",
2605 log_error ("function definition in evaluate_numeric_expr");
2612 log_error ("evaluate_numeric_expression: bogus opcode %d", expr
-> op
);
2616 /* Return data hanging off of an option cache structure, or if there
2617 isn't any, evaluate the expression hanging off of it and return the
2618 result of that evaluation. There should never be both an expression
2619 and a valid data_string. */
2621 int evaluate_option_cache (result
, packet
, lease
, client_state
,
2622 in_options
, cfg_options
, scope
, oc
, file
, line
)
2623 struct data_string
*result
;
2624 struct packet
*packet
;
2625 struct lease
*lease
;
2626 struct client_state
*client_state
;
2627 struct option_state
*in_options
;
2628 struct option_state
*cfg_options
;
2629 struct binding_scope
**scope
;
2630 struct option_cache
*oc
;
2634 if (oc
-> data
.len
) {
2635 data_string_copy (result
, &oc
-> data
, file
, line
);
2638 if (!oc
-> expression
)
2640 return evaluate_data_expression (result
, packet
, lease
, client_state
,
2641 in_options
, cfg_options
, scope
,
2642 oc
-> expression
, file
, line
);
2645 /* Evaluate an option cache and extract a boolean from the result,
2646 returning the boolean. Return false if there is no data. */
2648 int evaluate_boolean_option_cache (ignorep
, packet
,
2649 lease
, client_state
, in_options
,
2650 cfg_options
, scope
, oc
, file
, line
)
2652 struct packet
*packet
;
2653 struct lease
*lease
;
2654 struct client_state
*client_state
;
2655 struct option_state
*in_options
;
2656 struct option_state
*cfg_options
;
2657 struct binding_scope
**scope
;
2658 struct option_cache
*oc
;
2662 struct data_string ds
;
2665 /* So that we can be called with option_lookup as an argument. */
2666 if (!oc
|| !in_options
)
2669 memset (&ds
, 0, sizeof ds
);
2670 if (!evaluate_option_cache (&ds
, packet
,
2671 lease
, client_state
, in_options
,
2672 cfg_options
, scope
, oc
, file
, line
))
2676 result
= ds
.data
[0];
2684 data_string_forget (&ds
, MDL
);
2689 /* Evaluate a boolean expression and return the result of the evaluation,
2690 or FALSE if it failed. */
2692 int evaluate_boolean_expression_result (ignorep
, packet
, lease
, client_state
,
2693 in_options
, cfg_options
, scope
, expr
)
2695 struct packet
*packet
;
2696 struct lease
*lease
;
2697 struct client_state
*client_state
;
2698 struct option_state
*in_options
;
2699 struct option_state
*cfg_options
;
2700 struct binding_scope
**scope
;
2701 struct expression
*expr
;
2705 /* So that we can be called with option_lookup as an argument. */
2709 if (!evaluate_boolean_expression (&result
, packet
, lease
, client_state
,
2710 in_options
, cfg_options
,
2723 /* Dereference an expression node, and if the reference count goes to zero,
2724 dereference any data it refers to, and then free it. */
2725 void expression_dereference (eptr
, file
, line
)
2726 struct expression
**eptr
;
2730 struct expression
*expr
= *eptr
;
2732 /* Zero the pointer. */
2733 *eptr
= (struct expression
*)0;
2735 /* Decrement the reference count. If it's nonzero, we're
2738 rc_register (file
, line
, eptr
, expr
, expr
-> refcnt
, 1, RC_MISC
);
2739 if (expr
-> refcnt
> 0)
2741 if (expr
-> refcnt
< 0) {
2742 log_error ("%s(%d): negative refcnt!", file
, line
);
2743 #if defined (DEBUG_RC_HISTORY)
2744 dump_rc_history (expr
);
2746 #if defined (POINTER_DEBUG)
2753 /* Dereference subexpressions. */
2754 switch (expr
-> op
) {
2755 /* All the binary operators can be handled the same way. */
2757 case expr_not_equal
:
2765 case expr_remainder
:
2766 case expr_binary_and
:
2767 case expr_binary_or
:
2768 case expr_binary_xor
:
2769 case expr_client_state
:
2770 if (expr
-> data
.equal
[0])
2771 expression_dereference (&expr
-> data
.equal
[0],
2773 if (expr
-> data
.equal
[1])
2774 expression_dereference (&expr
-> data
.equal
[1],
2778 case expr_substring
:
2779 if (expr
-> data
.substring
.expr
)
2780 expression_dereference (&expr
-> data
.substring
.expr
,
2782 if (expr
-> data
.substring
.offset
)
2783 expression_dereference (&expr
-> data
.substring
.offset
,
2785 if (expr
-> data
.substring
.len
)
2786 expression_dereference (&expr
-> data
.substring
.len
,
2791 if (expr
-> data
.suffix
.expr
)
2792 expression_dereference (&expr
-> data
.suffix
.expr
,
2794 if (expr
-> data
.suffix
.len
)
2795 expression_dereference (&expr
-> data
.suffix
.len
,
2800 if (expr
-> data
.not)
2801 expression_dereference (&expr
-> data
.not, file
, line
);
2805 if (expr
-> data
.packet
.offset
)
2806 expression_dereference (&expr
-> data
.packet
.offset
,
2808 if (expr
-> data
.packet
.len
)
2809 expression_dereference (&expr
-> data
.packet
.len
,
2813 case expr_extract_int8
:
2814 case expr_extract_int16
:
2815 case expr_extract_int32
:
2816 if (expr
-> data
.extract_int
)
2817 expression_dereference (&expr
-> data
.extract_int
,
2821 case expr_encode_int8
:
2822 case expr_encode_int16
:
2823 case expr_encode_int32
:
2824 if (expr
-> data
.encode_int
)
2825 expression_dereference (&expr
-> data
.encode_int
,
2829 case expr_encapsulate
:
2830 case expr_const_data
:
2831 data_string_forget (&expr
-> data
.const_data
, file
, line
);
2834 case expr_host_lookup
:
2835 if (expr
-> data
.host_lookup
)
2836 dns_host_entry_dereference (&expr
-> data
.host_lookup
,
2840 case expr_binary_to_ascii
:
2841 if (expr
-> data
.b2a
.base
)
2842 expression_dereference (&expr
-> data
.b2a
.base
,
2844 if (expr
-> data
.b2a
.width
)
2845 expression_dereference (&expr
-> data
.b2a
.width
,
2847 if (expr
-> data
.b2a
.seperator
)
2848 expression_dereference (&expr
-> data
.b2a
.seperator
,
2850 if (expr
-> data
.b2a
.buffer
)
2851 expression_dereference (&expr
-> data
.b2a
.buffer
,
2855 case expr_pick_first_value
:
2856 if (expr
-> data
.pick_first_value
.car
)
2857 expression_dereference (&expr
-> data
.pick_first_value
.car
,
2859 if (expr
-> data
.pick_first_value
.cdr
)
2860 expression_dereference (&expr
-> data
.pick_first_value
.cdr
,
2865 if (expr
-> data
.reverse
.width
)
2866 expression_dereference (&expr
-> data
.reverse
.width
,
2868 if (expr
-> data
.reverse
.buffer
)
2869 expression_dereference
2870 (&expr
-> data
.reverse
.buffer
, file
, line
);
2873 case expr_dns_transaction
:
2874 if (expr
-> data
.dns_transaction
.car
)
2875 expression_dereference (&expr
-> data
.dns_transaction
.car
,
2877 if (expr
-> data
.dns_transaction
.cdr
)
2878 expression_dereference (&expr
-> data
.dns_transaction
.cdr
,
2883 if (expr
-> data
.ns_add
.rrname
)
2884 expression_dereference (&expr
-> data
.ns_add
.rrname
,
2886 if (expr
-> data
.ns_add
.rrdata
)
2887 expression_dereference (&expr
-> data
.ns_add
.rrdata
,
2889 if (expr
-> data
.ns_add
.ttl
)
2890 expression_dereference (&expr
-> data
.ns_add
.ttl
,
2894 case expr_ns_delete
:
2895 case expr_ns_exists
:
2896 case expr_ns_not_exists
:
2897 if (expr
-> data
.ns_delete
.rrname
)
2898 expression_dereference (&expr
-> data
.ns_delete
.rrname
,
2900 if (expr
-> data
.ns_delete
.rrdata
)
2901 expression_dereference (&expr
-> data
.ns_delete
.rrdata
,
2905 case expr_variable_reference
:
2906 case expr_variable_exists
:
2907 if (expr
-> data
.variable
)
2908 dfree (expr
-> data
.variable
, file
, line
);
2912 if (expr
-> data
.funcall
.name
)
2913 dfree (expr
-> data
.funcall
.name
, file
, line
);
2914 if (expr
-> data
.funcall
.arglist
)
2915 expression_dereference (&expr
-> data
.funcall
.arglist
,
2920 if (expr
-> data
.arg
.val
)
2921 expression_dereference (&expr
-> data
.arg
.val
,
2923 if (expr
-> data
.arg
.next
)
2924 expression_dereference (&expr
-> data
.arg
.next
,
2929 fundef_dereference (&expr
-> data
.func
, file
, line
);
2932 /* No subexpressions. */
2933 case expr_leased_address
:
2934 case expr_lease_time
:
2937 case expr_const_int
:
2949 free_expression (expr
, MDL
);
2952 int is_dns_expression (expr
)
2953 struct expression
*expr
;
2955 return (expr
-> op
== expr_ns_add
||
2956 expr
-> op
== expr_ns_delete
||
2957 expr
-> op
== expr_ns_exists
||
2958 expr
-> op
== expr_ns_not_exists
);
2961 int is_boolean_expression (expr
)
2962 struct expression
*expr
;
2964 return (expr
-> op
== expr_check
||
2965 expr
-> op
== expr_exists
||
2966 expr
-> op
== expr_variable_exists
||
2967 expr
-> op
== expr_equal
||
2968 expr
-> op
== expr_not_equal
||
2969 expr
-> op
== expr_and
||
2970 expr
-> op
== expr_or
||
2971 expr
-> op
== expr_not
||
2972 expr
-> op
== expr_known
||
2973 expr
-> op
== expr_static
);
2976 int is_data_expression (expr
)
2977 struct expression
*expr
;
2979 return (expr
-> op
== expr_substring
||
2980 expr
-> op
== expr_suffix
||
2981 expr
-> op
== expr_option
||
2982 expr
-> op
== expr_hardware
||
2983 expr
-> op
== expr_const_data
||
2984 expr
-> op
== expr_packet
||
2985 expr
-> op
== expr_concat
||
2986 expr
-> op
== expr_encapsulate
||
2987 expr
-> op
== expr_encode_int8
||
2988 expr
-> op
== expr_encode_int16
||
2989 expr
-> op
== expr_encode_int32
||
2990 expr
-> op
== expr_host_lookup
||
2991 expr
-> op
== expr_binary_to_ascii
||
2992 expr
-> op
== expr_filename
||
2993 expr
-> op
== expr_sname
||
2994 expr
-> op
== expr_reverse
||
2995 expr
-> op
== expr_pick_first_value
||
2996 expr
-> op
== expr_host_decl_name
||
2997 expr
-> op
== expr_leased_address
||
2998 expr
-> op
== expr_config_option
||
2999 expr
-> op
== expr_null
);
3002 int is_numeric_expression (expr
)
3003 struct expression
*expr
;
3005 return (expr
-> op
== expr_extract_int8
||
3006 expr
-> op
== expr_extract_int16
||
3007 expr
-> op
== expr_extract_int32
||
3008 expr
-> op
== expr_const_int
||
3009 expr
-> op
== expr_lease_time
||
3010 expr
-> op
== expr_dns_transaction
||
3011 expr
-> op
== expr_add
||
3012 expr
-> op
== expr_subtract
||
3013 expr
-> op
== expr_multiply
||
3014 expr
-> op
== expr_divide
||
3015 expr
-> op
== expr_remainder
||
3016 expr
-> op
== expr_binary_and
||
3017 expr
-> op
== expr_binary_or
||
3018 expr
-> op
== expr_binary_xor
||
3019 expr
-> op
== expr_client_state
);
3022 int is_compound_expression (expr
)
3023 struct expression
*expr
;
3025 return (expr
-> op
== expr_ns_add
||
3026 expr
-> op
== expr_ns_delete
||
3027 expr
-> op
== expr_ns_exists
||
3028 expr
-> op
== expr_ns_not_exists
||
3029 expr
-> op
== expr_substring
||
3030 expr
-> op
== expr_suffix
||
3031 expr
-> op
== expr_option
||
3032 expr
-> op
== expr_concat
||
3033 expr
-> op
== expr_encode_int8
||
3034 expr
-> op
== expr_encode_int16
||
3035 expr
-> op
== expr_encode_int32
||
3036 expr
-> op
== expr_binary_to_ascii
||
3037 expr
-> op
== expr_reverse
||
3038 expr
-> op
== expr_pick_first_value
||
3039 expr
-> op
== expr_config_option
||
3040 expr
-> op
== expr_extract_int8
||
3041 expr
-> op
== expr_extract_int16
||
3042 expr
-> op
== expr_extract_int32
||
3043 expr
-> op
== expr_dns_transaction
);
3046 static int op_val
PROTO ((enum expr_op
));
3048 static int op_val (op
)
3056 case expr_substring
:
3059 case expr_encapsulate
:
3060 case expr_host_lookup
:
3065 case expr_const_data
:
3066 case expr_extract_int8
:
3067 case expr_extract_int16
:
3068 case expr_extract_int32
:
3069 case expr_encode_int8
:
3070 case expr_encode_int16
:
3071 case expr_encode_int32
:
3072 case expr_const_int
:
3074 case expr_variable_exists
:
3076 case expr_binary_to_ascii
:
3080 case expr_pick_first_value
:
3081 case expr_host_decl_name
:
3082 case expr_config_option
:
3083 case expr_leased_address
:
3084 case expr_lease_time
:
3085 case expr_dns_transaction
:
3087 case expr_variable_reference
:
3089 case expr_ns_delete
:
3090 case expr_ns_exists
:
3091 case expr_ns_not_exists
:
3095 /* XXXDPN: Need to assign sane precedences to these. */
3096 case expr_binary_and
:
3097 case expr_binary_or
:
3098 case expr_binary_xor
:
3099 case expr_client_state
:
3103 case expr_not_equal
:
3116 case expr_remainder
:
3122 int op_precedence (op1
, op2
)
3123 enum expr_op op1
, op2
;
3126 return op_val (op1
) - op_val (op2
);
3129 enum expression_context
expression_context (struct expression
*expr
)
3131 if (is_data_expression (expr
))
3132 return context_data
;
3133 if (is_numeric_expression (expr
))
3134 return context_numeric
;
3135 if (is_boolean_expression (expr
))
3136 return context_boolean
;
3137 if (is_dns_expression (expr
))
3142 enum expression_context
op_context (op
)
3146 /* XXX Why aren't these specific? */
3151 case expr_substring
:
3154 case expr_encapsulate
:
3155 case expr_host_lookup
:
3160 case expr_const_data
:
3161 case expr_extract_int8
:
3162 case expr_extract_int16
:
3163 case expr_extract_int32
:
3164 case expr_encode_int8
:
3165 case expr_encode_int16
:
3166 case expr_encode_int32
:
3167 case expr_const_int
:
3169 case expr_variable_exists
:
3171 case expr_binary_to_ascii
:
3175 case expr_pick_first_value
:
3176 case expr_host_decl_name
:
3177 case expr_config_option
:
3178 case expr_leased_address
:
3179 case expr_lease_time
:
3181 case expr_variable_reference
:
3183 case expr_ns_delete
:
3184 case expr_ns_exists
:
3185 case expr_ns_not_exists
:
3186 case expr_dns_transaction
:
3193 case expr_not_equal
:
3194 return context_data
;
3197 return context_boolean
;
3200 return context_boolean
;
3206 case expr_remainder
:
3207 case expr_binary_and
:
3208 case expr_binary_or
:
3209 case expr_binary_xor
:
3210 case expr_client_state
:
3211 return context_numeric
;
3216 int write_expression (file
, expr
, col
, indent
, firstp
)
3218 struct expression
*expr
;
3223 struct expression
*e
;
3229 /* If this promises to be a fat expression, start a new line. */
3230 if (!firstp
&& is_compound_expression (expr
)) {
3231 indent_spaces (file
, indent
);
3235 switch (expr
-> op
) {
3237 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3241 col
= token_print_indent (file
, col
, indent
, "", "", "check");
3242 col
= token_print_indent_concat (file
, col
, indent
,
3244 expr
-> data
.check
-> name
,
3248 case expr_not_equal
:
3255 col
= write_expression (file
, expr
-> data
.equal
[0],
3257 col
= token_print_indent (file
, col
, indent
, " ", " ", s
);
3258 col
= write_expression (file
, expr
-> data
.equal
[1],
3259 col
, indent
+ 2, 0);
3262 case expr_substring
:
3263 col
= token_print_indent (file
, col
, indent
, "", "",
3265 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3267 col
= write_expression (file
, expr
-> data
.substring
.expr
,
3269 col
= token_print_indent (file
, col
, indent
, "", " ", ",");
3270 col
= write_expression (file
, expr
-> data
.substring
.offset
,
3272 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3273 col
= write_expression (file
, expr
-> data
.substring
.len
,
3275 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3279 col
= token_print_indent (file
, col
, indent
, "", "", "suffix");
3280 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3282 col
= write_expression (file
, expr
-> data
.suffix
.expr
,
3284 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3285 col
= write_expression (file
, expr
-> data
.suffix
.len
,
3287 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3292 col
= token_print_indent (file
, col
, indent
, "", "",
3294 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3298 col
= write_expression (file
, e
-> data
.concat
[0],
3301 if (!e
-> data
.concat
[1])
3303 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3304 if (e
-> data
.concat
[1] -> op
== expr_concat
) {
3305 e
= e
-> data
.concat
[1];
3308 col
= write_expression (file
, e
-> data
.concat
[1],
3311 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3314 case expr_host_lookup
:
3315 col
= token_print_indent (file
, col
, indent
, "", "",
3317 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3318 col
= token_print_indent_concat
3319 (file
, col
, indent
, "", "",
3320 "\"", expr
-> data
.host_lookup
-> hostname
, "\"",
3322 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3341 case expr_remainder
:
3345 case expr_binary_and
:
3349 case expr_binary_or
:
3353 case expr_binary_xor
:
3366 col
= token_print_indent (file
, col
, indent
, "", " ", "not");
3367 col
= write_expression (file
,
3368 expr
-> data
.not, col
, indent
+ 2, 1);
3375 col
= token_print_indent (file
, col
, indent
, "", "", s
);
3377 if (expr
-> data
.option
-> universe
!= &dhcp_universe
) {
3378 col
= token_print_indent (file
, col
, indent
,
3380 (expr
-> data
.option
->
3382 col
= token_print_indent (file
, col
, indent
, "", "",
3384 col
= token_print_indent (file
, col
, indent
, "", "",
3385 expr
-> data
.option
-> name
);
3387 col
= token_print_indent (file
, col
, indent
, " ", "",
3388 expr
-> data
.option
-> name
);
3393 col
= token_print_indent (file
, col
, indent
, "", "",
3398 col
= token_print_indent (file
, col
, indent
, "", "",
3400 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3402 col
= write_expression (file
, expr
-> data
.packet
.offset
,
3404 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3405 col
= write_expression (file
, expr
-> data
.packet
.len
,
3407 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3410 case expr_const_data
:
3411 col
= token_indent_data_string (file
, col
, indent
, "", "",
3412 &expr
-> data
.const_data
);
3415 case expr_extract_int8
:
3418 col
= token_print_indent (file
, col
, indent
, "", "",
3420 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3422 col
= write_expression (file
, expr
-> data
.extract_int
,
3424 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3425 sprintf (obuf
, "%d", width
);
3426 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3427 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3430 case expr_extract_int16
:
3434 case expr_extract_int32
:
3438 case expr_encode_int8
:
3441 col
= token_print_indent (file
, col
, indent
, "", "",
3443 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3445 col
= write_expression (file
, expr
-> data
.extract_int
,
3447 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3448 sprintf (obuf
, "%d", width
);
3449 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3450 col
= token_print_indent (file
, col
, indent
, "", "",
3454 case expr_encode_int16
:
3458 case expr_encode_int32
:
3462 case expr_const_int
:
3463 sprintf (obuf
, "%lu", expr
-> data
.const_int
);
3464 col
= token_print_indent (file
, col
, indent
, "", "", obuf
);
3469 goto print_option_name
;
3471 case expr_encapsulate
:
3472 col
= token_print_indent (file
, col
, indent
, "", "",
3474 col
= token_indent_data_string (file
, col
, indent
, " ", "",
3475 &expr
-> data
.encapsulate
);
3479 col
= token_print_indent (file
, col
, indent
, "", "", "known");
3483 col
= token_print_indent (file
, col
, indent
, "", "",
3485 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3487 col
= write_expression (file
, expr
-> data
.reverse
.width
,
3489 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3490 col
= write_expression (file
, expr
-> data
.reverse
.buffer
,
3492 col
= token_print_indent (file
, col
, indent
, "", "",
3496 case expr_leased_address
:
3497 col
= token_print_indent (file
, col
, indent
, "", "",
3501 case expr_client_state
:
3502 col
= token_print_indent (file
, col
, indent
, "", "",
3506 case expr_binary_to_ascii
:
3507 col
= token_print_indent (file
, col
, indent
, "", "",
3509 col
= token_print_indent (file
, col
, indent
, " ", "",
3512 col
= write_expression (file
, expr
-> data
.b2a
.base
,
3514 col
= token_print_indent (file
, col
, scol
, "", " ",
3516 col
= write_expression (file
, expr
-> data
.b2a
.width
,
3518 col
= token_print_indent (file
, col
, scol
, "", " ",
3520 col
= write_expression (file
, expr
-> data
.b2a
.seperator
,
3522 col
= token_print_indent (file
, col
, scol
, "", " ",
3524 col
= write_expression (file
, expr
-> data
.b2a
.buffer
,
3526 col
= token_print_indent (file
, col
, indent
, "", "",
3530 case expr_config_option
:
3531 s
= "config-option";
3532 goto print_option_name
;
3534 case expr_host_decl_name
:
3535 col
= token_print_indent (file
, col
, indent
, "", "",
3539 case expr_pick_first_value
:
3541 col
= token_print_indent (file
, col
, indent
, "", "",
3543 col
= token_print_indent (file
, col
, indent
, " ", "",
3548 col
= write_expression (file
,
3549 e
-> data
.pick_first_value
.car
,
3552 /* We're being very lisp-like right now - instead of
3553 representing this expression as (first middle . last) we're
3554 representing it as (first middle last), which means that the
3555 tail cdr is always nil. Apologies to non-wisp-lizards - may
3556 this obscure way of describing the problem motivate you to
3557 learn more about the one true computing language. */
3558 if (!e
-> data
.pick_first_value
.cdr
)
3560 col
= token_print_indent (file
, col
, scol
, "", " ",
3562 if (e
-> data
.pick_first_value
.cdr
-> op
==
3563 expr_pick_first_value
) {
3564 e
= e
-> data
.pick_first_value
.cdr
;
3567 col
= write_expression (file
,
3568 e
-> data
.pick_first_value
.cdr
,
3571 col
= token_print_indent (file
, col
, indent
, "", "",
3575 case expr_lease_time
:
3576 col
= token_print_indent (file
, col
, indent
, "", "",
3580 case expr_dns_transaction
:
3581 col
= token_print_indent (file
, col
, indent
, "", "",
3583 col
= token_print_indent (file
, col
, indent
, " ", "",
3587 e
&& e
-> op
== expr_dns_transaction
;
3588 e
= e
-> data
.dns_transaction
.cdr
) {
3594 col
= write_expression (file
,
3595 e
-> data
.dns_transaction
.car
,
3597 if (e
-> data
.dns_transaction
.cdr
)
3598 col
= token_print_indent (file
, col
, scol
,
3602 col
= write_expression (file
, e
, col
, scol
, 0);
3603 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3607 col
= token_print_indent (file
, col
, indent
, "", "",
3609 col
= token_print_indent (file
, col
, indent
, " ", "",
3612 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3613 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3614 col
= token_print_indent (file
, col
, scol
, "", " ",
3616 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3617 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3618 col
= token_print_indent (file
, col
, scol
, "", " ",
3620 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3622 col
= token_print_indent (file
, col
, scol
, "", " ",
3624 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3626 col
= token_print_indent (file
, col
, scol
, "", " ",
3628 col
= write_expression (file
, expr
-> data
.ns_add
.ttl
,
3630 col
= token_print_indent (file
, col
, indent
, "", "",
3634 case expr_ns_delete
:
3635 col
= token_print_indent (file
, col
, indent
, "", "",
3637 col
= token_print_indent (file
, col
, indent
, " ", "",
3641 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3642 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3643 col
= token_print_indent (file
, col
, scol
, "", " ",
3645 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3646 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3647 col
= token_print_indent (file
, col
, scol
, "", " ",
3649 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3651 col
= token_print_indent (file
, col
, scol
, "", " ",
3653 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3655 col
= token_print_indent (file
, col
, indent
, "", "",
3659 case expr_ns_exists
:
3660 col
= token_print_indent (file
, col
, indent
, "", "",
3662 col
= token_print_indent (file
, col
, indent
, " ", "",
3664 goto finish_ns_small
;
3666 case expr_ns_not_exists
:
3667 col
= token_print_indent (file
, col
, indent
, "", "",
3669 col
= token_print_indent (file
, col
, indent
, " ", "",
3671 goto finish_ns_small
;
3674 col
= token_print_indent (file
, col
, indent
, "", "",
3679 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3682 case expr_variable_reference
:
3683 col
= token_print_indent (file
, indent
, indent
, "", "",
3684 expr
-> data
.variable
);
3687 case expr_variable_exists
:
3688 col
= token_print_indent (file
, indent
, indent
, "", "",
3690 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3691 col
= token_print_indent (file
, col
, indent
, "", "",
3692 expr
-> data
.variable
);
3693 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3697 log_fatal ("invalid expression type in print_expression: %d",
3703 struct binding
*find_binding (struct binding_scope
*scope
, const char *name
)
3706 struct binding_scope
*s
;
3708 for (s
= scope
; s
; s
= s
-> outer
) {
3709 for (bp
= s
-> bindings
; bp
; bp
= bp
-> next
) {
3710 if (!strcasecmp (name
, bp
-> name
)) {
3715 return (struct binding
*)0;
3718 int free_bindings (struct binding_scope
*scope
, const char *file
, int line
)
3720 struct binding
*bp
, *next
;
3722 for (bp
= scope
-> bindings
; bp
; bp
= next
) {
3725 dfree (bp
-> name
, file
, line
);
3727 binding_value_dereference (&bp
-> value
, file
, line
);
3728 dfree (bp
, file
, line
);
3730 scope
-> bindings
= (struct binding
*)0;
3734 int binding_scope_dereference (ptr
, file
, line
)
3735 struct binding_scope
**ptr
;
3739 struct binding_scope
*binding_scope
;
3741 if (!ptr
|| !*ptr
) {
3742 log_error ("%s(%d): null pointer", file
, line
);
3743 #if defined (POINTER_DEBUG)
3750 binding_scope
= *ptr
;
3751 *ptr
= (struct binding_scope
*)0;
3752 --binding_scope
-> refcnt
;
3753 rc_register (file
, line
, ptr
,
3754 binding_scope
, binding_scope
-> refcnt
, 1, RC_MISC
);
3755 if (binding_scope
-> refcnt
> 0)
3758 if (binding_scope
-> refcnt
< 0) {
3759 log_error ("%s(%d): negative refcnt!", file
, line
);
3760 #if defined (DEBUG_RC_HISTORY)
3761 dump_rc_history (binding_scope
);
3763 #if defined (POINTER_DEBUG)
3770 free_bindings (binding_scope
, file
, line
);
3771 if (binding_scope
-> outer
)
3772 binding_scope_dereference (&binding_scope
-> outer
, MDL
);
3773 dfree (binding_scope
, file
, line
);
3777 int fundef_dereference (ptr
, file
, line
)
3778 struct fundef
**ptr
;
3782 struct fundef
*bp
= *ptr
;
3783 struct string_list
*sp
, *next
;
3786 log_error ("%s(%d): null pointer", file
, line
);
3787 #if defined (POINTER_DEBUG)
3795 log_error ("%s(%d): null pointer", file
, line
);
3796 #if defined (POINTER_DEBUG)
3804 rc_register (file
, line
, ptr
, bp
, bp
-> refcnt
, 1, RC_MISC
);
3805 if (bp
-> refcnt
< 0) {
3806 log_error ("%s(%d): negative refcnt!", file
, line
);
3807 #if defined (DEBUG_RC_HISTORY)
3808 dump_rc_history (bp
);
3810 #if defined (POINTER_DEBUG)
3816 if (!bp
-> refcnt
) {
3817 for (sp
= bp
-> args
; sp
; sp
= next
) {
3819 dfree (sp
, file
, line
);
3821 if (bp
-> statements
)
3822 executable_statement_dereference (&bp
-> statements
,
3824 dfree (bp
, file
, line
);
3826 *ptr
= (struct fundef
*)0;
3830 #if defined (NOTYET) /* Post 3.0 final. */
3831 int data_subexpression_length (int *rv
,
3832 struct expression
*expr
)
3834 int crhs
, clhs
, llhs
, lrhs
;
3835 switch (expr
-> op
) {
3836 case expr_substring
:
3837 if (expr
-> data
.substring
.len
&&
3838 expr
-> data
.substring
.len
-> op
== expr_const_int
) {
3840 (int)expr
-> data
.substring
.len
-> data
.const_int
);
3847 if (expr
-> data
.suffix
.len
&&
3848 expr
-> data
.suffix
.len
-> op
== expr_const_int
) {
3850 (int)expr
-> data
.suffix
.len
-> data
.const_int
);
3856 clhs
= data_subexpression_length (&llhs
,
3857 expr
-> data
.concat
[0]);
3858 crhs
= data_subexpression_length (&lrhs
,
3859 expr
-> data
.concat
[1]);
3860 if (crhs
== 0 || clhs
== 0)
3869 case expr_const_data
:
3870 *rv
= expr
-> data
.const_data
.len
;
3874 return data_subexpression_length (rv
,
3875 expr
-> data
.reverse
.buffer
);
3877 case expr_leased_address
:
3878 case expr_lease_time
:
3882 case expr_pick_first_value
:
3883 clhs
= data_subexpression_length (&llhs
,
3884 expr
-> data
.concat
[0]);
3885 crhs
= data_subexpression_length (&lrhs
,
3886 expr
-> data
.concat
[1]);
3887 if (crhs
== 0 || clhs
== 0)
3895 case expr_binary_to_ascii
:
3896 case expr_config_option
:
3897 case expr_host_decl_name
:
3898 case expr_encapsulate
:
3901 case expr_host_lookup
:
3910 case expr_extract_int8
:
3911 case expr_extract_int16
:
3912 case expr_extract_int32
:
3913 case expr_encode_int8
:
3914 case expr_encode_int16
:
3915 case expr_encode_int32
:
3916 case expr_const_int
:
3919 case expr_dns_transaction
:
3922 case expr_ns_delete
:
3923 case expr_ns_exists
:
3924 case expr_ns_not_exists
:
3925 case expr_not_equal
:
3927 case expr_variable_exists
:
3928 case expr_variable_reference
:
3936 case expr_remainder
:
3937 case expr_binary_and
:
3938 case expr_binary_or
:
3939 case expr_binary_xor
:
3940 case expr_client_state
:
3946 int expr_valid_for_context (struct expression
*expr
,
3947 enum expression_context context
)
3949 /* We don't know at parse time what type of value a function may
3950 return, so we can't flag an error on it. */
3951 if (expr
-> op
== expr_funcall
||
3952 expr
-> op
== expr_variable_reference
)
3959 case context_boolean
:
3960 if (is_boolean_expression (expr
))
3965 if (is_data_expression (expr
))
3969 case context_numeric
:
3970 if (is_numeric_expression (expr
))
3975 if (is_dns_expression (expr
)) {
3980 case context_data_or_numeric
:
3981 if (is_numeric_expression (expr
) ||
3982 is_data_expression (expr
)) {
3987 case context_function
:
3988 if (expr
-> op
== expr_function
)
3996 struct binding
*create_binding (struct binding_scope
**scope
, const char *name
)
3998 struct binding
*binding
;
4001 if (!binding_scope_allocate (scope
, MDL
))
4002 return (struct binding
*)0;
4005 binding
= find_binding (*scope
, name
);
4007 binding
= dmalloc (sizeof *binding
, MDL
);
4009 return (struct binding
*)0;
4011 memset (binding
, 0, sizeof *binding
);
4012 binding
-> name
= dmalloc (strlen (name
) + 1, MDL
);
4013 if (!binding
-> name
) {
4014 dfree (binding
, MDL
);
4015 return (struct binding
*)0;
4017 strcpy (binding
-> name
, name
);
4019 binding
-> next
= (*scope
) -> bindings
;
4020 (*scope
) -> bindings
= binding
;
4027 int bind_ds_value (struct binding_scope
**scope
,
4029 struct data_string
*value
)
4031 struct binding
*binding
;
4033 binding
= create_binding (scope
, name
);
4037 if (binding
-> value
)
4038 binding_value_dereference (&binding
-> value
, MDL
);
4040 if (!binding_value_allocate (&binding
-> value
, MDL
))
4043 data_string_copy (&binding
-> value
-> value
.data
, value
, MDL
);
4044 binding
-> value
-> type
= binding_data
;
4050 int find_bound_string (struct data_string
*value
,
4051 struct binding_scope
*scope
,
4054 struct binding
*binding
;
4056 binding
= find_binding (scope
, name
);
4058 !binding
-> value
||
4059 binding
-> value
-> type
!= binding_data
)
4062 if (binding
-> value
-> value
.data
.terminated
) {
4063 data_string_copy (value
, &binding
-> value
-> value
.data
, MDL
);
4065 buffer_allocate (&value
-> buffer
,
4066 binding
-> value
-> value
.data
.len
,
4068 if (!value
-> buffer
)
4071 memcpy (value
-> buffer
-> data
,
4072 binding
-> value
-> value
.data
.data
,
4073 binding
-> value
-> value
.data
.len
);
4074 value
-> data
= value
-> buffer
-> data
;
4075 value
-> len
= binding
-> value
-> value
.data
.len
;
4081 int unset (struct binding_scope
*scope
, const char *name
)
4083 struct binding
*binding
;
4085 binding
= find_binding (scope
, name
);
4087 if (binding
-> value
)
4088 binding_value_dereference
4089 (&binding
-> value
, MDL
);
4095 /* vim: set tabstop=8: */