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$ 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
;
654 if (!result
|| *result
) {
655 log_error ("evaluate_dns_expression called with non-null %s",
657 #if defined (POINTER_DEBUG)
664 switch (expr
-> op
) {
665 #if defined (NSUPDATE)
667 r0
= evaluate_numeric_expression (&ttl
, packet
, lease
,
669 in_options
, cfg_options
,
671 expr
-> data
.ns_add
.ttl
);
678 case expr_ns_not_exists
:
681 memset (&name
, 0, sizeof name
);
682 r1
= evaluate_data_expression (&name
, packet
, lease
,
684 in_options
, cfg_options
, scope
,
685 expr
-> data
.ns_add
.rrname
,
688 /* The result of the evaluation may or may not
689 be NUL-terminated, but we need it
690 terminated for sure, so we have to allocate
691 a buffer and terminate it. */
692 tname
= dmalloc (name
.len
+ 1, MDL
);
696 data_string_forget (&name
, MDL
);
698 memcpy (tname
, name
.data
, name
.len
);
699 tname
[name
.len
] = 0;
700 memset (&data
, 0, sizeof data
);
701 r2
= evaluate_data_expression
702 (&data
, packet
, lease
, client_state
,
703 in_options
, cfg_options
, scope
,
704 expr
-> data
.ns_add
.rrdata
, MDL
);
710 if (r0
&& r1
&& (r2
|| expr
-> op
!= expr_ns_add
)) {
711 *result
= minires_mkupdrec (((expr
-> op
== expr_ns_add
||
712 expr
-> op
== expr_ns_delete
)
713 ? S_UPDATE
: S_PREREQ
),
715 expr
-> data
.ns_add
.rrclass
,
716 expr
-> data
.ns_add
.rrtype
,
721 data_string_forget (&data
, MDL
);
726 /* As a special case, if we get exactly
727 four bytes of data, it's an IP address
728 represented as a 32-bit quantity, which
729 is actually what we *should* be getting
730 here. Because res_mkupdrec is currently
731 broken and expects a dotted quad, convert
732 it. This should be fixed when the new
733 resolver is merged. */
735 (*result
) -> r_data_ephem
=
737 if (!(*result
) -> r_data_ephem
)
739 (*result
) -> r_data
=
740 (*result
) -> r_data_ephem
;
741 /*%Audit% 16 bytes max. %2004.06.17,Safe%*/
742 sprintf ((char *)(*result
) -> r_data_ephem
,
744 data
.data
[0] & 0xff,
745 data
.data
[1] & 0xff,
746 data
.data
[2] & 0xff,
747 data
.data
[3] & 0xff);
748 (*result
) -> r_size
=
749 strlen ((const char *)
750 (*result
) -> r_data
);
752 (*result
) -> r_size
= data
.len
;
753 (*result
) -> r_data_ephem
=
754 dmalloc (data
.len
, MDL
);
755 if (!(*result
) -> r_data_ephem
) {
756 dpngood
: /* double plus ungood. */
757 minires_freeupdrec (*result
);
761 (*result
) -> r_data
=
762 (*result
) -> r_data_ephem
;
763 memcpy ((*result
) -> r_data_ephem
,
764 data
.data
, data
.len
);
767 (*result
) -> r_data
= 0;
768 (*result
) -> r_size
= 0;
770 switch (expr
-> op
) {
772 (*result
) -> r_opcode
= ADD
;
775 (*result
) -> r_opcode
= DELETE
;
778 (*result
) -> r_opcode
= YXRRSET
;
780 case expr_ns_not_exists
:
781 (*result
) -> r_opcode
= NXRRSET
;
784 /* Can't happen, but satisfy gcc. */
791 data_string_forget (&name
, MDL
);
795 data_string_forget (&data
, MDL
);
796 /* One flaw in the thinking here: an IP address and an
797 ASCII string both look like data expressions, but
798 for A records, we want an ASCII string, not a
799 binary IP address. Do I need to turn binary IP
800 addresses into a seperate type? */
802 (r2
|| expr
-> op
!= expr_ns_add
) && *result
);
808 case expr_ns_not_exists
:
812 log_error ("%s: dns values for functions not supported.",
813 expr
-> data
.funcall
.name
);
816 case expr_variable_reference
:
817 log_error ("%s: dns values for variables not supported.",
818 expr
-> data
.variable
);
831 case expr_variable_exists
:
832 log_error ("Boolean opcode in evaluate_dns_expression: %d",
841 case expr_const_data
:
844 case expr_encapsulate
:
845 case expr_host_lookup
:
846 case expr_encode_int8
:
847 case expr_encode_int16
:
848 case expr_encode_int32
:
849 case expr_binary_to_ascii
:
853 case expr_pick_first_value
:
854 case expr_host_decl_name
:
855 case expr_config_option
:
856 case expr_leased_address
:
858 log_error ("Data opcode in evaluate_dns_expression: %d",
862 case expr_extract_int8
:
863 case expr_extract_int16
:
864 case expr_extract_int32
:
866 case expr_lease_time
:
867 case expr_dns_transaction
:
873 case expr_binary_and
:
875 case expr_binary_xor
:
876 case expr_client_state
:
877 log_error ("Numeric opcode in evaluate_dns_expression: %d",
882 log_error ("Function opcode in evaluate_dns_expression: %d",
890 log_error ("Bogus opcode in evaluate_dns_expression: %d",
894 #endif /* defined (NSUPDATE) */
896 int evaluate_boolean_expression (result
, packet
, lease
, client_state
,
897 in_options
, cfg_options
, scope
, expr
)
899 struct packet
*packet
;
901 struct client_state
*client_state
;
902 struct option_state
*in_options
;
903 struct option_state
*cfg_options
;
904 struct binding_scope
**scope
;
905 struct expression
*expr
;
907 struct data_string left
;
908 // struct data_string right;
909 // struct data_string rrtype, rrname, rrdata;
910 // unsigned long ttl;
911 // int srrtype, srrname, srrdata;
915 struct binding
*binding
;
916 struct binding_value
*bv
, *obv
;
918 switch (expr
-> op
) {
920 *result
= check_collection (packet
, lease
,
922 #if defined (DEBUG_EXPRESSIONS)
923 log_debug ("bool: check (%s) returns %s",
924 expr
-> data
.check
-> name
,
925 *result
? "true" : "false");
931 bv
= obv
= (struct binding_value
*)0;
932 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
933 in_options
, cfg_options
, scope
,
934 expr
-> data
.equal
[0], MDL
);
935 sright
= evaluate_expression (&obv
, packet
, lease
,
936 client_state
, in_options
,
938 expr
-> data
.equal
[1], MDL
);
939 if (sleft
&& sright
) {
940 if (bv
-> type
!= obv
-> type
)
941 *result
= expr
-> op
== expr_not_equal
;
943 switch (obv
-> type
) {
944 case binding_boolean
:
945 if (bv
-> value
.boolean
== obv
-> value
.boolean
)
946 *result
= expr
-> op
== expr_equal
;
948 *result
= expr
-> op
== expr_not_equal
;
952 if ((bv
-> value
.data
.len
==
953 obv
-> value
.data
.len
) &&
954 !memcmp (bv
-> value
.data
.data
,
955 obv
-> value
.data
.data
,
956 obv
-> value
.data
.len
))
957 *result
= expr
-> op
== expr_equal
;
959 *result
= expr
-> op
== expr_not_equal
;
962 case binding_numeric
:
963 if (bv
-> value
.intval
== obv
-> value
.intval
)
964 *result
= expr
-> op
== expr_equal
;
966 *result
= expr
-> op
== expr_not_equal
;
970 #if defined (NSUPDATE)
971 /* XXX This should be a comparison for equal
972 XXX values, not for identity. */
973 if (bv
-> value
.dns
== obv
-> value
.dns
)
974 *result
= expr
-> op
== expr_equal
;
976 *result
= expr
-> op
== expr_not_equal
;
978 *result
= expr
-> op
== expr_not_equal
;
982 case binding_function
:
983 if (bv
-> value
.fundef
== obv
-> value
.fundef
)
984 *result
= expr
-> op
== expr_equal
;
986 *result
= expr
-> op
== expr_not_equal
;
989 *result
= expr
-> op
== expr_not_equal
;
993 } else if (!sleft
&& !sright
)
994 *result
= expr
-> op
== expr_equal
;
996 *result
= expr
-> op
== expr_not_equal
;
998 #if defined (DEBUG_EXPRESSIONS)
999 log_debug ("bool: %sequal = %s",
1000 expr
-> op
== expr_not_equal
? "not" : "",
1001 (*result
? "true" : "false"));
1004 binding_value_dereference (&bv
, MDL
);
1006 binding_value_dereference (&obv
, MDL
);
1010 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1012 in_options
, cfg_options
,
1014 expr
-> data
.and [0]);
1016 sright
= evaluate_boolean_expression
1017 (&bright
, packet
, lease
, client_state
,
1018 in_options
, cfg_options
,
1019 scope
, expr
-> data
.and [1]);
1021 sright
= bright
= 0;
1023 #if defined (DEBUG_EXPRESSIONS)
1024 log_debug ("bool: and (%s, %s) = %s",
1025 sleft
? (bleft
? "true" : "false") : "NULL",
1026 sright
? (bright
? "true" : "false") : "NULL",
1028 ? (bleft
&& bright
? "true" : "false") : "NULL"));
1030 if (sleft
&& sright
) {
1031 *result
= bleft
&& bright
;
1038 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1040 in_options
, cfg_options
,
1042 expr
-> data
.or [0]);
1043 if (!sleft
|| !bleft
)
1044 sright
= evaluate_boolean_expression
1045 (&bright
, packet
, lease
, client_state
,
1046 in_options
, cfg_options
,
1047 scope
, expr
-> data
.or [1]);
1050 #if defined (DEBUG_EXPRESSIONS)
1051 log_debug ("bool: or (%s, %s) = %s",
1052 sleft
? (bleft
? "true" : "false") : "NULL",
1053 sright
? (bright
? "true" : "false") : "NULL",
1055 ? (bleft
|| bright
? "true" : "false") : "NULL"));
1057 if (sleft
|| sright
) {
1058 *result
= bleft
|| bright
;
1064 sleft
= evaluate_boolean_expression (&bleft
, packet
, lease
,
1066 in_options
, cfg_options
,
1069 #if defined (DEBUG_EXPRESSIONS)
1070 log_debug ("bool: not (%s) = %s",
1071 sleft
? (bleft
? "true" : "false") : "NULL",
1073 ? (!bleft
? "true" : "false") : "NULL"));
1083 memset (&left
, 0, sizeof left
);
1085 !get_option (&left
, expr
-> data
.exists
-> universe
,
1086 packet
, lease
, client_state
,
1087 in_options
, cfg_options
, in_options
,
1088 scope
, expr
-> data
.exists
-> code
, MDL
))
1092 data_string_forget (&left
, MDL
);
1094 #if defined (DEBUG_EXPRESSIONS)
1095 log_debug ("bool: exists %s.%s = %s",
1096 expr
-> data
.option
-> universe
-> name
,
1097 expr
-> data
.option
-> name
,
1098 *result
? "true" : "false");
1104 #if defined (DEBUG_EXPRESSIONS)
1105 log_debug ("bool: known = NULL");
1109 #if defined (DEBUG_EXPRESSIONS)
1110 log_debug ("bool: known = %s",
1111 packet
-> known
? "true" : "false");
1113 *result
= packet
-> known
;
1117 if (!lease
|| !(lease
-> flags
& STATIC_LEASE
)) {
1118 #if defined (DEBUG_EXPRESSIONS)
1119 log_debug ("bool: static = false (%s %s %s %d)",
1121 (lease
&& (lease
-> flags
& STATIC_LEASE
)
1123 piaddr (lease
-> ip_addr
),
1124 lease
? lease
-> flags
: 0);
1129 #if defined (DEBUG_EXPRESSIONS)
1130 log_debug ("bool: static = true");
1135 case expr_variable_exists
:
1136 if (scope
&& *scope
) {
1137 binding
= find_binding (*scope
, expr
-> data
.variable
);
1140 if (binding
-> value
)
1148 #if defined (DEBUG_EXPRESSIONS)
1149 log_debug ("boolean: %s? = %s", expr
-> data
.variable
,
1150 *result
? "true" : "false");
1154 case expr_variable_reference
:
1155 if (scope
&& *scope
) {
1156 binding
= find_binding (*scope
, expr
-> data
.variable
);
1158 if (binding
&& binding
-> value
) {
1159 if (binding
-> value
-> type
==
1161 *result
= binding
-> value
-> value
.boolean
;
1164 log_error ("binding type %d in %s.",
1165 binding
-> value
-> type
,
1166 "evaluate_boolean_expression");
1173 #if defined (DEBUG_EXPRESSIONS)
1174 log_debug ("boolean: %s = %s", expr
-> data
.variable
,
1175 sleft
? (*result
? "true" : "false") : "NULL");
1180 bv
= (struct binding_value
*)0;
1181 sleft
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1182 in_options
, cfg_options
,
1185 if (bv
-> type
!= binding_boolean
)
1186 log_error ("%s() returned type %d in %s.",
1187 expr
-> data
.funcall
.name
,
1189 "evaluate_boolean_expression");
1191 *result
= bv
-> value
.boolean
;
1192 binding_value_dereference (&bv
, MDL
);
1194 #if defined (DEBUG_EXPRESSIONS)
1195 log_debug ("boolean: %s() = %s", expr
-> data
.funcall
.name
,
1196 sleft
? (*result
? "true" : "false") : "NULL");
1202 case expr_substring
:
1206 case expr_const_data
:
1209 case expr_encapsulate
:
1210 case expr_host_lookup
:
1211 case expr_encode_int8
:
1212 case expr_encode_int16
:
1213 case expr_encode_int32
:
1214 case expr_binary_to_ascii
:
1216 case expr_pick_first_value
:
1217 case expr_host_decl_name
:
1218 case expr_config_option
:
1219 case expr_leased_address
:
1223 log_error ("Data opcode in evaluate_boolean_expression: %d",
1227 case expr_extract_int8
:
1228 case expr_extract_int16
:
1229 case expr_extract_int32
:
1230 case expr_const_int
:
1231 case expr_lease_time
:
1232 case expr_dns_transaction
:
1237 case expr_remainder
:
1238 case expr_binary_and
:
1239 case expr_binary_or
:
1240 case expr_binary_xor
:
1241 case expr_client_state
:
1242 log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1247 case expr_ns_delete
:
1248 case expr_ns_exists
:
1249 case expr_ns_not_exists
:
1250 log_error ("dns opcode in evaluate_boolean_expression: %d",
1255 log_error ("function definition in evaluate_boolean_expr");
1262 log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1267 int evaluate_data_expression (result
, packet
, lease
, client_state
,
1268 in_options
, cfg_options
, scope
, expr
, file
, line
)
1269 struct data_string
*result
;
1270 struct packet
*packet
;
1271 struct lease
*lease
;
1272 struct client_state
*client_state
;
1273 struct option_state
*in_options
;
1274 struct option_state
*cfg_options
;
1275 struct binding_scope
**scope
;
1276 struct expression
*expr
;
1280 struct data_string data
, other
;
1281 unsigned long offset
, len
;
1285 struct binding
*binding
;
1287 struct binding_value
*bv
;
1289 switch (expr
-> op
) {
1290 /* Extract N bytes starting at byte M of a data string. */
1291 case expr_substring
:
1292 memset (&data
, 0, sizeof data
);
1293 s0
= evaluate_data_expression (&data
, packet
, lease
,
1295 in_options
, cfg_options
, scope
,
1296 expr
-> data
.substring
.expr
,
1299 /* Evaluate the offset and length. */
1300 s1
= evaluate_numeric_expression
1301 (&offset
, packet
, lease
, client_state
, in_options
,
1302 cfg_options
, scope
, expr
-> data
.substring
.offset
);
1303 s2
= evaluate_numeric_expression (&len
, packet
, lease
,
1305 in_options
, cfg_options
,
1307 expr
-> data
.substring
.len
);
1309 if (s0
&& s1
&& s2
) {
1310 /* If the offset is after end of the string,
1311 return an empty string. Otherwise, do the
1312 adjustments and return what's left. */
1313 if (data
.len
> offset
) {
1314 data_string_copy (result
, &data
, file
, line
);
1315 result
-> len
-= offset
;
1316 if (result
-> len
> len
) {
1317 result
-> len
= len
;
1318 result
-> terminated
= 0;
1320 result
-> data
+= offset
;
1326 #if defined (DEBUG_EXPRESSIONS)
1327 log_debug ("data: substring (%s, %s, %s) = %s",
1328 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1329 s1
? print_dec_1 (offset
) : "NULL",
1330 s2
? print_dec_2 (len
) : "NULL",
1331 (s3
? print_hex_2 (result
-> len
, result
-> data
, 30)
1335 data_string_forget (&data
, MDL
);
1341 /* Extract the last N bytes of a data string. */
1343 memset (&data
, 0, sizeof data
);
1344 s0
= evaluate_data_expression (&data
, packet
, lease
,
1346 in_options
, cfg_options
, scope
,
1347 expr
-> data
.suffix
.expr
, MDL
);
1348 /* Evaluate the length. */
1349 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1351 in_options
, cfg_options
,
1353 expr
-> data
.suffix
.len
);
1355 data_string_copy (result
, &data
, file
, line
);
1357 /* If we are returning the last N bytes of a
1358 string whose length is <= N, just return
1359 the string - otherwise, compute a new
1360 starting address and decrease the
1362 if (data
.len
> len
) {
1363 result
-> data
+= data
.len
- len
;
1364 result
-> len
= len
;
1366 data_string_forget (&data
, MDL
);
1369 #if defined (DEBUG_EXPRESSIONS)
1370 log_debug ("data: suffix (%s, %s) = %s",
1371 s0
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1372 s1
? print_dec_1 (len
) : "NULL",
1374 ? print_hex_2 (result
-> len
, result
-> data
, 30)
1379 /* Extract an option. */
1382 s0
= get_option (result
,
1383 expr
-> data
.option
-> universe
,
1384 packet
, lease
, client_state
,
1385 in_options
, cfg_options
, in_options
,
1386 scope
, expr
-> data
.option
-> code
,
1391 #if defined (DEBUG_EXPRESSIONS)
1392 log_debug ("data: option %s.%s = %s",
1393 expr
-> data
.option
-> universe
-> name
,
1394 expr
-> data
.option
-> name
,
1395 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1400 case expr_config_option
:
1402 s0
= get_option (result
,
1403 expr
-> data
.option
-> universe
,
1404 packet
, lease
, client_state
,
1405 in_options
, cfg_options
, cfg_options
,
1406 scope
, expr
-> data
.option
-> code
,
1411 #if defined (DEBUG_EXPRESSIONS)
1412 log_debug ("data: config-option %s.%s = %s",
1413 expr
-> data
.option
-> universe
-> name
,
1414 expr
-> data
.option
-> name
,
1415 s0
? print_hex_1 (result
-> len
, result
-> data
, 60)
1420 /* Combine the hardware type and address. */
1422 /* On the client, hardware is our hardware. */
1424 memset (result
, 0, sizeof *result
);
1426 client_state
-> interface
-> hw_address
.hbuf
;
1428 client_state
-> interface
-> hw_address
.hlen
;
1429 #if defined (DEBUG_EXPRESSIONS)
1430 log_debug ("data: hardware = %s",
1431 print_hex_1 (result
-> len
,
1432 result
-> data
, 60));
1437 /* The server cares about the client's hardware address,
1438 so only in the case where we are examining a packet can
1439 we return anything. */
1440 if (!packet
|| !packet
-> raw
) {
1441 log_error ("data: hardware: raw packet not available");
1444 if (packet
-> raw
-> hlen
> sizeof packet
-> raw
-> chaddr
) {
1445 log_error ("data: hardware: invalid hlen (%d)\n",
1446 packet
-> raw
-> hlen
);
1449 result
-> len
= packet
-> raw
-> hlen
+ 1;
1450 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1452 result
-> data
= &result
-> buffer
-> data
[0];
1453 result
-> buffer
-> data
[0] = packet
-> raw
-> htype
;
1454 memcpy (&result
-> buffer
-> data
[1],
1455 packet
-> raw
-> chaddr
,
1456 packet
-> raw
-> hlen
);
1457 result
-> terminated
= 0;
1459 log_error ("data: hardware: no memory for buffer.");
1462 #if defined (DEBUG_EXPRESSIONS)
1463 log_debug ("data: hardware = %s",
1464 print_hex_1 (result
-> len
, result
-> data
, 60));
1468 /* Extract part of the raw packet. */
1470 if (!packet
|| !packet
-> raw
) {
1471 log_error ("data: packet: raw packet not available");
1475 s0
= evaluate_numeric_expression (&offset
, packet
, lease
,
1477 in_options
, cfg_options
,
1479 expr
-> data
.packet
.offset
);
1480 s1
= evaluate_numeric_expression (&len
,
1481 packet
, lease
, client_state
,
1482 in_options
, cfg_options
,
1484 expr
-> data
.packet
.len
);
1485 if (s0
&& s1
&& offset
< packet
-> packet_length
) {
1486 if (offset
+ len
> packet
-> packet_length
)
1488 packet
-> packet_length
- offset
;
1490 result
-> len
= len
;
1491 if (buffer_allocate (&result
-> buffer
,
1492 result
-> len
, file
, line
)) {
1493 result
-> data
= &result
-> buffer
-> data
[0];
1494 memcpy (result
-> buffer
-> data
,
1495 (((unsigned char *)(packet
-> raw
))
1496 + offset
), result
-> len
);
1497 result
-> terminated
= 0;
1499 log_error ("data: packet: no buffer memory.");
1505 #if defined (DEBUG_EXPRESSIONS)
1506 log_debug ("data: packet (%ld, %ld) = %s",
1508 s2
? print_hex_1 (result
-> len
,
1509 result
-> data
, 60) : NULL
);
1513 /* The encapsulation of all defined options in an
1515 case expr_encapsulate
:
1517 s0
= option_space_encapsulate
1518 (result
, packet
, lease
, client_state
,
1519 in_options
, cfg_options
, scope
,
1520 &expr
-> data
.encapsulate
);
1524 #if defined (DEBUG_EXPRESSIONS)
1525 log_debug ("data: encapsulate (%s) = %s",
1526 expr
-> data
.encapsulate
.data
,
1527 s0
? print_hex_1 (result
-> len
,
1528 result
-> data
, 60) : "NULL");
1532 /* Some constant data... */
1533 case expr_const_data
:
1534 #if defined (DEBUG_EXPRESSIONS)
1535 log_debug ("data: const = %s",
1536 print_hex_1 (expr
-> data
.const_data
.len
,
1537 expr
-> data
.const_data
.data
, 60));
1539 data_string_copy (result
,
1540 &expr
-> data
.const_data
, file
, line
);
1543 /* Hostname lookup... */
1544 case expr_host_lookup
:
1545 s0
= do_host_lookup (result
, expr
-> data
.host_lookup
);
1546 #if defined (DEBUG_EXPRESSIONS)
1547 log_debug ("data: DNS lookup (%s) = %s",
1548 expr
-> data
.host_lookup
-> hostname
,
1550 ? print_dotted_quads (result
-> len
, result
-> data
)
1555 /* Concatenation... */
1557 memset (&data
, 0, sizeof data
);
1558 s0
= evaluate_data_expression (&data
, packet
, lease
,
1560 in_options
, cfg_options
, scope
,
1561 expr
-> data
.concat
[0], MDL
);
1562 memset (&other
, 0, sizeof other
);
1563 s1
= evaluate_data_expression (&other
, packet
, lease
,
1565 in_options
, cfg_options
, scope
,
1566 expr
-> data
.concat
[1], MDL
);
1569 result
-> len
= data
.len
+ other
.len
;
1570 if (!buffer_allocate (&result
-> buffer
,
1571 (result
-> len
+ other
.terminated
),
1573 log_error ("data: concat: no memory");
1575 data_string_forget (&data
, MDL
);
1576 data_string_forget (&other
, MDL
);
1579 result
-> data
= &result
-> buffer
-> data
[0];
1580 memcpy (result
-> buffer
-> data
, data
.data
, data
.len
);
1581 memcpy (&result
-> buffer
-> data
[data
.len
],
1582 other
.data
, other
.len
+ other
.terminated
);
1586 data_string_forget (&data
, MDL
);
1588 data_string_forget (&other
, MDL
);
1589 #if defined (DEBUG_EXPRESSIONS)
1590 log_debug ("data: concat (%s, %s) = %s",
1591 s0
? print_hex_1 (data
.len
, data
.data
, 20) : "NULL",
1592 s1
? print_hex_2 (other
.len
, other
.data
, 20) : "NULL",
1594 ? print_hex_3 (result
-> len
, result
-> data
, 30)
1599 case expr_encode_int8
:
1600 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1602 in_options
, cfg_options
,
1604 expr
-> data
.encode_int
);
1607 if (!buffer_allocate (&result
-> buffer
,
1609 log_error ("data: encode_int8: no memory");
1613 result
-> data
= &result
-> buffer
-> data
[0];
1614 result
-> buffer
-> data
[0] = len
;
1619 #if defined (DEBUG_EXPRESSIONS)
1621 log_debug ("data: encode_int8 (NULL) = NULL");
1623 log_debug ("data: encode_int8 (%ld) = %s", len
,
1624 print_hex_2 (result
-> len
,
1625 result
-> data
, 20));
1630 case expr_encode_int16
:
1631 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1633 in_options
, cfg_options
,
1635 expr
-> data
.encode_int
);
1638 if (!buffer_allocate (&result
-> buffer
, 2,
1640 log_error ("data: encode_int16: no memory");
1644 result
-> data
= &result
-> buffer
-> data
[0];
1645 putUShort (result
-> buffer
-> data
, len
);
1650 #if defined (DEBUG_EXPRESSIONS)
1652 log_debug ("data: encode_int16 (NULL) = NULL");
1654 log_debug ("data: encode_int16 (%ld) = %s", len
,
1655 print_hex_2 (result
-> len
,
1656 result
-> data
, 20));
1660 case expr_encode_int32
:
1661 s0
= evaluate_numeric_expression (&len
, packet
, lease
,
1663 in_options
, cfg_options
,
1665 expr
-> data
.encode_int
);
1668 if (!buffer_allocate (&result
-> buffer
, 4,
1670 log_error ("data: encode_int32: no memory");
1674 result
-> data
= &result
-> buffer
-> data
[0];
1675 putULong (result
-> buffer
-> data
, len
);
1680 #if defined (DEBUG_EXPRESSIONS)
1682 log_debug ("data: encode_int32 (NULL) = NULL");
1684 log_debug ("data: encode_int32 (%ld) = %s", len
,
1685 print_hex_2 (result
-> len
,
1686 result
-> data
, 20));
1690 case expr_binary_to_ascii
:
1691 /* Evaluate the base (offset) and width (len): */
1692 s0
= evaluate_numeric_expression
1693 (&offset
, packet
, lease
, client_state
, in_options
,
1694 cfg_options
, scope
, expr
-> data
.b2a
.base
);
1695 s1
= evaluate_numeric_expression (&len
, packet
, lease
,
1697 in_options
, cfg_options
,
1699 expr
-> data
.b2a
.width
);
1701 /* Evaluate the seperator string. */
1702 memset (&data
, 0, sizeof data
);
1703 s2
= evaluate_data_expression (&data
, packet
, lease
,
1705 in_options
, cfg_options
, scope
,
1706 expr
-> data
.b2a
.seperator
,
1709 /* Evaluate the data to be converted. */
1710 memset (&other
, 0, sizeof other
);
1711 s3
= evaluate_data_expression (&other
, packet
, lease
,
1713 in_options
, cfg_options
, scope
,
1714 expr
-> data
.b2a
.buffer
, MDL
);
1716 if (s0
&& s1
&& s2
&& s3
) {
1719 if (len
!= 8 && len
!= 16 && len
!= 32) {
1720 log_info ("binary_to_ascii: %s %ld!",
1721 "invalid width", len
);
1727 /* The buffer must be a multiple of the number's
1729 if (other
.len
% len
) {
1730 log_info ("binary-to-ascii: %s %d %s %ld!",
1731 "length of buffer", other
.len
,
1732 "not a multiple of width", len
);
1737 /* Count the width of the output. */
1739 for (i
= 0; i
< other
.len
; i
+= len
) {
1742 if (other
.data
[i
] < 8)
1744 else if (other
.data
[i
] < 64)
1748 } else if (offset
== 10) {
1749 if (other
.data
[i
] < 10)
1751 else if (other
.data
[i
] < 100)
1755 } else if (offset
== 16) {
1756 if (other
.data
[i
] < 16)
1761 buflen
+= (converted_length
1765 buflen
+= (converted_length
1768 if (i
+ len
!= other
.len
)
1772 if (!buffer_allocate (&result
-> buffer
,
1773 buflen
+ 1, file
, line
)) {
1774 log_error ("data: binary-to-ascii: no memory");
1778 result
-> data
= &result
-> buffer
-> data
[0];
1779 result
-> len
= buflen
;
1780 result
-> terminated
= 1;
1783 for (i
= 0; i
< other
.len
; i
+= len
) {
1784 buflen
+= (binary_to_ascii
1785 (&result
-> buffer
-> data
[buflen
],
1786 &other
.data
[i
], offset
, len
));
1787 if (i
+ len
!= other
.len
) {
1789 buffer
-> data
[buflen
],
1790 data
.data
, data
.len
);
1794 /* NUL terminate. */
1795 result
-> buffer
-> data
[buflen
] = 0;
1801 #if defined (DEBUG_EXPRESSIONS)
1802 log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
1803 s0
? print_dec_1 (offset
) : "NULL",
1804 s1
? print_dec_2 (len
) : "NULL",
1805 s2
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1806 s3
? print_hex_2 (other
.len
, other
.data
, 30) : "NULL",
1807 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1811 data_string_forget (&data
, MDL
);
1813 data_string_forget (&other
, MDL
);
1819 /* Evaluate the width (len): */
1820 s0
= evaluate_numeric_expression
1821 (&len
, packet
, lease
, client_state
, in_options
,
1822 cfg_options
, scope
, expr
-> data
.reverse
.width
);
1824 /* Evaluate the data. */
1825 memset (&data
, 0, sizeof data
);
1826 s1
= evaluate_data_expression (&data
, packet
, lease
,
1828 in_options
, cfg_options
, scope
,
1829 expr
-> data
.reverse
.buffer
,
1836 /* The buffer must be a multiple of the number's
1838 if (data
.len
% len
) {
1839 log_info ("reverse: %s %d %s %ld!",
1840 "length of buffer", data
.len
,
1841 "not a multiple of width", len
);
1846 /* XXX reverse in place? I don't think we can. */
1847 if (!buffer_allocate (&result
-> buffer
,
1848 data
.len
, file
, line
)) {
1849 log_error ("data: reverse: no memory");
1853 result
-> data
= &result
-> buffer
-> data
[0];
1854 result
-> len
= data
.len
;
1855 result
-> terminated
= 0;
1857 for (i
= 0; i
< data
.len
; i
+= len
) {
1858 memcpy (&result
-> buffer
-> data
[i
],
1859 &data
.data
[data
.len
- i
- len
], len
);
1866 #if defined (DEBUG_EXPRESSIONS)
1867 log_debug ("data: reverse (%s, %s) = %s",
1868 s0
? print_dec_1 (len
) : "NULL",
1869 s1
? print_hex_1 (data
.len
, data
.data
, 30) : "NULL",
1870 (status
? print_hex_3 (result
-> len
, result
-> data
, 30)
1874 data_string_forget (&data
, MDL
);
1879 case expr_leased_address
:
1881 log_error ("data: leased_address: not available");
1884 result
-> len
= lease
-> ip_addr
.len
;
1885 if (buffer_allocate (&result
-> buffer
, result
-> len
,
1887 result
-> data
= &result
-> buffer
-> data
[0];
1888 memcpy (&result
-> buffer
-> data
[0],
1889 lease
-> ip_addr
.iabuf
, lease
-> ip_addr
.len
);
1890 result
-> terminated
= 0;
1892 log_error ("data: leased-address: no memory.");
1895 #if defined (DEBUG_EXPRESSIONS)
1896 log_debug ("data: leased-address = %s",
1897 print_hex_1 (result
-> len
, result
-> data
, 60));
1901 case expr_pick_first_value
:
1902 memset (&data
, 0, sizeof data
);
1903 if ((evaluate_data_expression
1905 lease
, client_state
, in_options
, cfg_options
,
1906 scope
, expr
-> data
.pick_first_value
.car
, MDL
))) {
1907 #if defined (DEBUG_EXPRESSIONS)
1908 log_debug ("data: pick_first_value (%s, xxx)",
1909 print_hex_1 (result
-> len
,
1910 result
-> data
, 40));
1915 if (expr
-> data
.pick_first_value
.cdr
&&
1916 (evaluate_data_expression
1918 lease
, client_state
, in_options
, cfg_options
,
1919 scope
, expr
-> data
.pick_first_value
.cdr
, MDL
))) {
1920 #if defined (DEBUG_EXPRESSIONS)
1921 log_debug ("data: pick_first_value (NULL, %s)",
1922 print_hex_1 (result
-> len
,
1923 result
-> data
, 40));
1928 #if defined (DEBUG_EXPRESSIONS)
1929 log_debug ("data: pick_first_value (NULL, NULL) = NULL");
1933 case expr_host_decl_name
:
1934 if (!lease
|| !lease
-> host
) {
1935 log_error ("data: host_decl_name: not available");
1938 result
-> len
= strlen (lease
-> host
-> name
);
1939 if (buffer_allocate (&result
-> buffer
,
1940 result
-> len
+ 1, file
, line
)) {
1941 result
-> data
= &result
-> buffer
-> data
[0];
1942 strcpy ((char *)&result
-> buffer
-> data
[0],
1943 lease
-> host
-> name
);
1944 result
-> terminated
= 1;
1946 log_error ("data: host-decl-name: no memory.");
1949 #if defined (DEBUG_EXPRESSIONS)
1950 log_debug ("data: host-decl-name = %s", lease
-> host
-> name
);
1955 #if defined (DEBUG_EXPRESSIONS)
1956 log_debug ("data: null = NULL");
1960 case expr_variable_reference
:
1961 if (scope
&& *scope
) {
1962 binding
= find_binding (*scope
, expr
-> data
.variable
);
1964 if (binding
&& binding
-> value
) {
1965 if (binding
-> value
-> type
== binding_data
) {
1966 data_string_copy (result
,
1967 &binding
-> value
-> value
.data
,
1970 } else if (binding
-> value
-> type
!= binding_data
) {
1971 log_error ("binding type %d in %s.",
1972 binding
-> value
-> type
,
1973 "evaluate_data_expression");
1981 #if defined (DEBUG_EXPRESSIONS)
1982 log_debug ("data: %s = %s", expr
-> data
.variable
,
1983 s0
? print_hex_1 (result
-> len
,
1984 result
-> data
, 50) : "NULL");
1989 bv
= (struct binding_value
*)0;
1990 s0
= evaluate_expression (&bv
, packet
, lease
, client_state
,
1991 in_options
, cfg_options
,
1994 if (bv
-> type
!= binding_data
)
1995 log_error ("%s() returned type %d in %s.",
1996 expr
-> data
.funcall
.name
,
1998 "evaluate_data_expression");
2000 data_string_copy (result
, &bv
-> value
.data
,
2002 binding_value_dereference (&bv
, MDL
);
2004 #if defined (DEBUG_EXPRESSIONS)
2005 log_debug ("data: %s = %s", expr
-> data
.funcall
.name
,
2006 s0
? print_hex_1 (result
-> len
,
2007 result
-> data
, 50) : "NULL");
2011 /* Extract the filename. */
2013 if (packet
&& packet
-> raw
-> file
[0]) {
2015 memchr (packet
-> raw
-> file
, 0,
2016 sizeof packet
-> raw
-> file
);
2018 fn
= ((char *)packet
-> raw
-> file
+
2019 sizeof packet
-> raw
-> file
);
2020 result
-> len
= fn
- &(packet
-> raw
-> file
[0]);
2021 if (buffer_allocate (&result
-> buffer
,
2022 result
-> len
+ 1, file
, line
)) {
2023 result
-> data
= &result
-> buffer
-> data
[0];
2024 memcpy (&result
-> buffer
-> data
[0],
2025 packet
-> raw
-> file
,
2027 result
-> buffer
-> data
[result
-> len
] = 0;
2028 result
-> terminated
= 1;
2031 log_error ("data: filename: no memory.");
2037 #if defined (DEBUG_EXPRESSIONS)
2038 log_info ("data: filename = \"%s\"",
2039 s0
? (const char *)(result
-> data
) : "NULL");
2043 /* Extract the server name. */
2045 if (packet
&& packet
-> raw
-> sname
[0]) {
2047 memchr (packet
-> raw
-> sname
, 0,
2048 sizeof packet
-> raw
-> sname
);
2050 fn
= ((char *)packet
-> raw
-> sname
+
2051 sizeof packet
-> raw
-> sname
);
2052 result
-> len
= fn
- &packet
-> raw
-> sname
[0];
2053 if (buffer_allocate (&result
-> buffer
,
2054 result
-> len
+ 1, file
, line
)) {
2055 result
-> data
= &result
-> buffer
-> data
[0];
2056 memcpy (&result
-> buffer
-> data
[0],
2057 packet
-> raw
-> sname
,
2059 result
-> buffer
-> data
[result
-> len
] = 0;
2060 result
-> terminated
= 1;
2063 log_error ("data: sname: no memory.");
2069 #if defined (DEBUG_EXPRESSIONS)
2070 log_info ("data: sname = \"%s\"",
2071 s0
? (const char *)(result
-> data
) : "NULL");
2077 case expr_not_equal
:
2086 case expr_variable_exists
:
2087 log_error ("Boolean opcode in evaluate_data_expression: %d",
2091 case expr_extract_int8
:
2092 case expr_extract_int16
:
2093 case expr_extract_int32
:
2094 case expr_const_int
:
2095 case expr_lease_time
:
2096 case expr_dns_transaction
:
2101 case expr_remainder
:
2102 case expr_binary_and
:
2103 case expr_binary_or
:
2104 case expr_binary_xor
:
2105 case expr_client_state
:
2106 log_error ("Numeric opcode in evaluate_data_expression: %d",
2111 case expr_ns_delete
:
2112 case expr_ns_exists
:
2113 case expr_ns_not_exists
:
2114 log_error ("dns update opcode in evaluate_data_expression: %d",
2119 log_error ("function definition in evaluate_data_expression");
2126 log_error ("Bogus opcode in evaluate_data_expression: %d", expr
-> op
);
2130 int evaluate_numeric_expression (result
, packet
, lease
, client_state
,
2131 in_options
, cfg_options
, scope
, expr
)
2132 unsigned long *result
;
2133 struct packet
*packet
;
2134 struct lease
*lease
;
2135 struct client_state
*client_state
;
2136 struct option_state
*in_options
;
2137 struct option_state
*cfg_options
;
2138 struct binding_scope
**scope
;
2139 struct expression
*expr
;
2141 struct data_string data
;
2142 int status
, sleft
, sright
;
2143 #if defined (NSUPDATE)
2147 struct expression
*cur
, *next
;
2148 struct binding
*binding
;
2149 struct binding_value
*bv
;
2150 unsigned long ileft
, iright
;
2152 switch (expr
-> op
) {
2155 case expr_not_equal
:
2164 case expr_variable_exists
:
2165 log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2169 case expr_substring
:
2173 case expr_const_data
:
2176 case expr_encapsulate
:
2177 case expr_host_lookup
:
2178 case expr_encode_int8
:
2179 case expr_encode_int16
:
2180 case expr_encode_int32
:
2181 case expr_binary_to_ascii
:
2185 case expr_pick_first_value
:
2186 case expr_host_decl_name
:
2187 case expr_config_option
:
2188 case expr_leased_address
:
2190 log_error ("Data opcode in evaluate_numeric_expression: %d",
2194 case expr_extract_int8
:
2195 memset (&data
, 0, sizeof data
);
2196 status
= evaluate_data_expression
2197 (&data
, packet
, lease
, client_state
, in_options
,
2198 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
);
2200 *result
= data
.data
[0];
2201 #if defined (DEBUG_EXPRESSIONS)
2202 log_debug ("num: extract_int8 (%s) = %s",
2203 status
? print_hex_1 (data
.len
, data
.data
, 60) : "NULL",
2204 status
? print_dec_1 (*result
) : "NULL" );
2206 if (status
) data_string_forget (&data
, MDL
);
2209 case expr_extract_int16
:
2210 memset (&data
, 0, sizeof data
);
2211 status
= (evaluate_data_expression
2212 (&data
, packet
, lease
, client_state
, in_options
,
2213 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2214 if (status
&& data
.len
>= 2)
2215 *result
= getUShort (data
.data
);
2216 #if defined (DEBUG_EXPRESSIONS)
2217 log_debug ("num: extract_int16 (%s) = %ld",
2218 ((status
&& data
.len
>= 2) ?
2219 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2222 if (status
) data_string_forget (&data
, MDL
);
2223 return (status
&& data
.len
>= 2);
2225 case expr_extract_int32
:
2226 memset (&data
, 0, sizeof data
);
2227 status
= (evaluate_data_expression
2228 (&data
, packet
, lease
, client_state
, in_options
,
2229 cfg_options
, scope
, expr
-> data
.extract_int
, MDL
));
2230 if (status
&& data
.len
>= 4)
2231 *result
= getULong (data
.data
);
2232 #if defined (DEBUG_EXPRESSIONS)
2233 log_debug ("num: extract_int32 (%s) = %ld",
2234 ((status
&& data
.len
>= 4) ?
2235 print_hex_1 (data
.len
, data
.data
, 60) : "NULL"),
2238 if (status
) data_string_forget (&data
, MDL
);
2239 return (status
&& data
.len
>= 4);
2241 case expr_const_int
:
2242 *result
= expr
-> data
.const_int
;
2243 #if defined (DEBUG_EXPRESSIONS)
2244 log_debug ("number: CONSTANT = %ld", *result
);
2248 case expr_lease_time
:
2250 log_error ("data: leased_lease: not available");
2253 if (lease
-> ends
< cur_time
) {
2254 log_error ("%s %lu when it is now %lu",
2255 "data: lease_time: lease ends at",
2256 (long)(lease
-> ends
), (long)cur_time
);
2259 *result
= lease
-> ends
- cur_time
;
2260 #if defined (DEBUG_EXPRESSIONS)
2261 log_debug ("number: lease-time = (%lu - %lu) = %ld",
2267 case expr_dns_transaction
:
2268 #if !defined (NSUPDATE)
2271 if (!resolver_inited
) {
2272 minires_ninit (&resolver_state
);
2273 resolver_inited
= 1;
2274 resolver_state
.retrans
= 1;
2275 resolver_state
.retry
= 1;
2280 next
= cur
-> data
.dns_transaction
.cdr
;
2282 status
= (evaluate_dns_expression
2284 lease
, client_state
, in_options
, cfg_options
,
2285 scope
, cur
-> data
.dns_transaction
.car
));
2288 ISC_LIST_APPEND (uq
, nut
, r_link
);
2292 /* Do the update and record the error code, if there was
2293 an error; otherwise set it to NOERROR. */
2294 *result
= minires_nupdate (&resolver_state
,
2295 ISC_LIST_HEAD (uq
));
2298 print_dns_status ((int)*result
, &uq
);
2301 while (!ISC_LIST_EMPTY (uq
)) {
2302 ns_updrec
*tmp
= ISC_LIST_HEAD (uq
);
2303 ISC_LIST_UNLINK (uq
, tmp
, r_link
);
2304 if (tmp
-> r_data_ephem
) {
2305 dfree (tmp
-> r_data_ephem
, MDL
);
2306 tmp
-> r_data
= (unsigned char *)0;
2307 tmp
-> r_data_ephem
= (unsigned char *)0;
2309 minires_freeupdrec (tmp
);
2312 #endif /* NSUPDATE */
2314 case expr_variable_reference
:
2315 if (scope
&& *scope
) {
2316 binding
= find_binding (*scope
, expr
-> data
.variable
);
2318 if (binding
&& binding
-> value
) {
2319 if (binding
-> value
-> type
== binding_numeric
) {
2320 *result
= binding
-> value
-> value
.intval
;
2323 log_error ("binding type %d in %s.",
2324 binding
-> value
-> type
,
2325 "evaluate_numeric_expression");
2332 #if defined (DEBUG_EXPRESSIONS)
2334 log_debug ("numeric: %s = %ld",
2335 expr
-> data
.variable
, *result
);
2337 log_debug ("numeric: %s = NULL",
2338 expr
-> data
.variable
);
2343 bv
= (struct binding_value
*)0;
2344 status
= evaluate_expression (&bv
, packet
, lease
,
2346 in_options
, cfg_options
,
2349 if (bv
-> type
!= binding_numeric
)
2350 log_error ("%s() returned type %d in %s.",
2351 expr
-> data
.funcall
.name
,
2353 "evaluate_numeric_expression");
2355 *result
= bv
-> value
.intval
;
2356 binding_value_dereference (&bv
, MDL
);
2358 #if defined (DEBUG_EXPRESSIONS)
2359 log_debug ("data: %s = %ld", expr
-> data
.funcall
.name
,
2360 status
? *result
: 0);
2365 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2367 in_options
, cfg_options
,
2369 expr
-> data
.and [0]);
2370 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2372 in_options
, cfg_options
,
2374 expr
-> data
.and [1]);
2376 #if defined (DEBUG_EXPRESSIONS)
2377 if (sleft
&& sright
)
2378 log_debug ("num: %ld + %ld = %ld",
2379 ileft
, iright
, ileft
+ iright
);
2381 log_debug ("num: %ld + NULL = NULL", ileft
);
2383 log_debug ("num: NULL + %ld = NULL", iright
);
2385 if (sleft
&& sright
) {
2386 *result
= ileft
+ iright
;
2392 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2394 in_options
, cfg_options
,
2396 expr
-> data
.and [0]);
2397 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2399 in_options
, cfg_options
,
2401 expr
-> data
.and [1]);
2403 #if defined (DEBUG_EXPRESSIONS)
2404 if (sleft
&& sright
)
2405 log_debug ("num: %ld - %ld = %ld",
2406 ileft
, iright
, ileft
- iright
);
2408 log_debug ("num: %ld - NULL = NULL", ileft
);
2410 log_debug ("num: NULL - %ld = NULL", iright
);
2412 if (sleft
&& sright
) {
2413 *result
= ileft
- iright
;
2419 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2421 in_options
, cfg_options
,
2423 expr
-> data
.and [0]);
2424 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2426 in_options
, cfg_options
,
2428 expr
-> data
.and [1]);
2430 #if defined (DEBUG_EXPRESSIONS)
2431 if (sleft
&& sright
)
2432 log_debug ("num: %ld * %ld = %ld",
2433 ileft
, iright
, ileft
* iright
);
2435 log_debug ("num: %ld * NULL = NULL", ileft
);
2437 log_debug ("num: NULL * %ld = NULL", iright
);
2439 if (sleft
&& sright
) {
2440 *result
= ileft
* iright
;
2446 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2448 in_options
, cfg_options
,
2450 expr
-> data
.and [0]);
2451 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2453 in_options
, cfg_options
,
2455 expr
-> data
.and [1]);
2457 #if defined (DEBUG_EXPRESSIONS)
2458 if (sleft
&& sright
) {
2460 log_debug ("num: %ld / %ld = %ld",
2461 ileft
, iright
, ileft
/ iright
);
2463 log_debug ("num: %ld / %ld = NULL",
2466 log_debug ("num: %ld / NULL = NULL", ileft
);
2468 log_debug ("num: NULL / %ld = NULL", iright
);
2470 if (sleft
&& sright
&& iright
) {
2471 *result
= ileft
/ iright
;
2476 case expr_remainder
:
2477 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2479 in_options
, cfg_options
,
2481 expr
-> data
.and [0]);
2482 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2484 in_options
, cfg_options
,
2486 expr
-> data
.and [1]);
2488 #if defined (DEBUG_EXPRESSIONS)
2489 if (sleft
&& sright
) {
2491 log_debug ("num: %ld %% %ld = %ld",
2492 ileft
, iright
, ileft
% iright
);
2494 log_debug ("num: %ld %% %ld = NULL",
2497 log_debug ("num: %ld %% NULL = NULL", ileft
);
2499 log_debug ("num: NULL %% %ld = NULL", iright
);
2501 if (sleft
&& sright
&& iright
) {
2502 *result
= ileft
% iright
;
2507 case expr_binary_and
:
2508 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2510 in_options
, cfg_options
,
2512 expr
-> data
.and [0]);
2513 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2515 in_options
, cfg_options
,
2517 expr
-> data
.and [1]);
2519 #if defined (DEBUG_EXPRESSIONS)
2520 if (sleft
&& sright
)
2521 log_debug ("num: %ld | %ld = %ld",
2522 ileft
, iright
, ileft
& iright
);
2524 log_debug ("num: %ld & NULL = NULL", ileft
);
2526 log_debug ("num: NULL & %ld = NULL", iright
);
2528 if (sleft
&& sright
) {
2529 *result
= ileft
& iright
;
2534 case expr_binary_or
:
2535 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2537 in_options
, cfg_options
,
2539 expr
-> data
.and [0]);
2540 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2542 in_options
, cfg_options
,
2544 expr
-> data
.and [1]);
2546 #if defined (DEBUG_EXPRESSIONS)
2547 if (sleft
&& sright
)
2548 log_debug ("num: %ld | %ld = %ld",
2549 ileft
, iright
, ileft
| iright
);
2551 log_debug ("num: %ld | NULL = NULL", ileft
);
2553 log_debug ("num: NULL | %ld = NULL", iright
);
2555 if (sleft
&& sright
) {
2556 *result
= ileft
| iright
;
2561 case expr_binary_xor
:
2562 sleft
= evaluate_numeric_expression (&ileft
, packet
, lease
,
2564 in_options
, cfg_options
,
2566 expr
-> data
.and [0]);
2567 sright
= evaluate_numeric_expression (&iright
, packet
, lease
,
2569 in_options
, cfg_options
,
2571 expr
-> data
.and [1]);
2573 #if defined (DEBUG_EXPRESSIONS)
2574 if (sleft
&& sright
)
2575 log_debug ("num: %ld ^ %ld = %ld",
2576 ileft
, iright
, ileft
^ iright
);
2578 log_debug ("num: %ld ^ NULL = NULL", ileft
);
2580 log_debug ("num: NULL ^ %ld = NULL", iright
);
2582 if (sleft
&& sright
) {
2583 *result
= ileft
^ iright
;
2588 case expr_client_state
:
2590 #if defined (DEBUG_EXPRESSIONS)
2591 log_debug ("num: client-state = %d",
2592 client_state
-> state
);
2594 *result
= client_state
-> state
;
2597 #if defined (DEBUG_EXPRESSIONS)
2598 log_debug ("num: client-state = NULL");
2604 case expr_ns_delete
:
2605 case expr_ns_exists
:
2606 case expr_ns_not_exists
:
2607 log_error ("dns opcode in evaluate_numeric_expression: %d",
2612 log_error ("function definition in evaluate_numeric_expr");
2619 log_error ("evaluate_numeric_expression: bogus opcode %d", expr
-> op
);
2623 /* Return data hanging off of an option cache structure, or if there
2624 isn't any, evaluate the expression hanging off of it and return the
2625 result of that evaluation. There should never be both an expression
2626 and a valid data_string. */
2628 int evaluate_option_cache (result
, packet
, lease
, client_state
,
2629 in_options
, cfg_options
, scope
, oc
, file
, line
)
2630 struct data_string
*result
;
2631 struct packet
*packet
;
2632 struct lease
*lease
;
2633 struct client_state
*client_state
;
2634 struct option_state
*in_options
;
2635 struct option_state
*cfg_options
;
2636 struct binding_scope
**scope
;
2637 struct option_cache
*oc
;
2641 if (oc
-> data
.len
) {
2642 data_string_copy (result
, &oc
-> data
, file
, line
);
2645 if (!oc
-> expression
)
2647 return evaluate_data_expression (result
, packet
, lease
, client_state
,
2648 in_options
, cfg_options
, scope
,
2649 oc
-> expression
, file
, line
);
2652 /* Evaluate an option cache and extract a boolean from the result,
2653 returning the boolean. Return false if there is no data. */
2655 int evaluate_boolean_option_cache (ignorep
, packet
,
2656 lease
, client_state
, in_options
,
2657 cfg_options
, scope
, oc
, file
, line
)
2659 struct packet
*packet
;
2660 struct lease
*lease
;
2661 struct client_state
*client_state
;
2662 struct option_state
*in_options
;
2663 struct option_state
*cfg_options
;
2664 struct binding_scope
**scope
;
2665 struct option_cache
*oc
;
2669 struct data_string ds
;
2672 /* So that we can be called with option_lookup as an argument. */
2673 if (!oc
|| !in_options
)
2676 memset (&ds
, 0, sizeof ds
);
2677 if (!evaluate_option_cache (&ds
, packet
,
2678 lease
, client_state
, in_options
,
2679 cfg_options
, scope
, oc
, file
, line
))
2683 result
= ds
.data
[0];
2691 data_string_forget (&ds
, MDL
);
2696 /* Evaluate a boolean expression and return the result of the evaluation,
2697 or FALSE if it failed. */
2699 int evaluate_boolean_expression_result (ignorep
, packet
, lease
, client_state
,
2700 in_options
, cfg_options
, scope
, expr
)
2702 struct packet
*packet
;
2703 struct lease
*lease
;
2704 struct client_state
*client_state
;
2705 struct option_state
*in_options
;
2706 struct option_state
*cfg_options
;
2707 struct binding_scope
**scope
;
2708 struct expression
*expr
;
2712 /* So that we can be called with option_lookup as an argument. */
2716 if (!evaluate_boolean_expression (&result
, packet
, lease
, client_state
,
2717 in_options
, cfg_options
,
2730 /* Dereference an expression node, and if the reference count goes to zero,
2731 dereference any data it refers to, and then free it. */
2732 void expression_dereference (eptr
, file
, line
)
2733 struct expression
**eptr
;
2737 struct expression
*expr
= *eptr
;
2739 /* Zero the pointer. */
2740 *eptr
= (struct expression
*)0;
2742 /* Decrement the reference count. If it's nonzero, we're
2745 rc_register (file
, line
, eptr
, expr
, expr
-> refcnt
, 1, RC_MISC
);
2746 if (expr
-> refcnt
> 0)
2748 if (expr
-> refcnt
< 0) {
2749 log_error ("%s(%d): negative refcnt!", file
, line
);
2750 #if defined (DEBUG_RC_HISTORY)
2751 dump_rc_history (expr
);
2753 #if defined (POINTER_DEBUG)
2760 /* Dereference subexpressions. */
2761 switch (expr
-> op
) {
2762 /* All the binary operators can be handled the same way. */
2764 case expr_not_equal
:
2772 case expr_remainder
:
2773 case expr_binary_and
:
2774 case expr_binary_or
:
2775 case expr_binary_xor
:
2776 case expr_client_state
:
2777 if (expr
-> data
.equal
[0])
2778 expression_dereference (&expr
-> data
.equal
[0],
2780 if (expr
-> data
.equal
[1])
2781 expression_dereference (&expr
-> data
.equal
[1],
2785 case expr_substring
:
2786 if (expr
-> data
.substring
.expr
)
2787 expression_dereference (&expr
-> data
.substring
.expr
,
2789 if (expr
-> data
.substring
.offset
)
2790 expression_dereference (&expr
-> data
.substring
.offset
,
2792 if (expr
-> data
.substring
.len
)
2793 expression_dereference (&expr
-> data
.substring
.len
,
2798 if (expr
-> data
.suffix
.expr
)
2799 expression_dereference (&expr
-> data
.suffix
.expr
,
2801 if (expr
-> data
.suffix
.len
)
2802 expression_dereference (&expr
-> data
.suffix
.len
,
2807 if (expr
-> data
.not)
2808 expression_dereference (&expr
-> data
.not, file
, line
);
2812 if (expr
-> data
.packet
.offset
)
2813 expression_dereference (&expr
-> data
.packet
.offset
,
2815 if (expr
-> data
.packet
.len
)
2816 expression_dereference (&expr
-> data
.packet
.len
,
2820 case expr_extract_int8
:
2821 case expr_extract_int16
:
2822 case expr_extract_int32
:
2823 if (expr
-> data
.extract_int
)
2824 expression_dereference (&expr
-> data
.extract_int
,
2828 case expr_encode_int8
:
2829 case expr_encode_int16
:
2830 case expr_encode_int32
:
2831 if (expr
-> data
.encode_int
)
2832 expression_dereference (&expr
-> data
.encode_int
,
2836 case expr_encapsulate
:
2837 case expr_const_data
:
2838 data_string_forget (&expr
-> data
.const_data
, file
, line
);
2841 case expr_host_lookup
:
2842 if (expr
-> data
.host_lookup
)
2843 dns_host_entry_dereference (&expr
-> data
.host_lookup
,
2847 case expr_binary_to_ascii
:
2848 if (expr
-> data
.b2a
.base
)
2849 expression_dereference (&expr
-> data
.b2a
.base
,
2851 if (expr
-> data
.b2a
.width
)
2852 expression_dereference (&expr
-> data
.b2a
.width
,
2854 if (expr
-> data
.b2a
.seperator
)
2855 expression_dereference (&expr
-> data
.b2a
.seperator
,
2857 if (expr
-> data
.b2a
.buffer
)
2858 expression_dereference (&expr
-> data
.b2a
.buffer
,
2862 case expr_pick_first_value
:
2863 if (expr
-> data
.pick_first_value
.car
)
2864 expression_dereference (&expr
-> data
.pick_first_value
.car
,
2866 if (expr
-> data
.pick_first_value
.cdr
)
2867 expression_dereference (&expr
-> data
.pick_first_value
.cdr
,
2872 if (expr
-> data
.reverse
.width
)
2873 expression_dereference (&expr
-> data
.reverse
.width
,
2875 if (expr
-> data
.reverse
.buffer
)
2876 expression_dereference
2877 (&expr
-> data
.reverse
.buffer
, file
, line
);
2880 case expr_dns_transaction
:
2881 if (expr
-> data
.dns_transaction
.car
)
2882 expression_dereference (&expr
-> data
.dns_transaction
.car
,
2884 if (expr
-> data
.dns_transaction
.cdr
)
2885 expression_dereference (&expr
-> data
.dns_transaction
.cdr
,
2890 if (expr
-> data
.ns_add
.rrname
)
2891 expression_dereference (&expr
-> data
.ns_add
.rrname
,
2893 if (expr
-> data
.ns_add
.rrdata
)
2894 expression_dereference (&expr
-> data
.ns_add
.rrdata
,
2896 if (expr
-> data
.ns_add
.ttl
)
2897 expression_dereference (&expr
-> data
.ns_add
.ttl
,
2901 case expr_ns_delete
:
2902 case expr_ns_exists
:
2903 case expr_ns_not_exists
:
2904 if (expr
-> data
.ns_delete
.rrname
)
2905 expression_dereference (&expr
-> data
.ns_delete
.rrname
,
2907 if (expr
-> data
.ns_delete
.rrdata
)
2908 expression_dereference (&expr
-> data
.ns_delete
.rrdata
,
2912 case expr_variable_reference
:
2913 case expr_variable_exists
:
2914 if (expr
-> data
.variable
)
2915 dfree (expr
-> data
.variable
, file
, line
);
2919 if (expr
-> data
.funcall
.name
)
2920 dfree (expr
-> data
.funcall
.name
, file
, line
);
2921 if (expr
-> data
.funcall
.arglist
)
2922 expression_dereference (&expr
-> data
.funcall
.arglist
,
2927 if (expr
-> data
.arg
.val
)
2928 expression_dereference (&expr
-> data
.arg
.val
,
2930 if (expr
-> data
.arg
.next
)
2931 expression_dereference (&expr
-> data
.arg
.next
,
2936 fundef_dereference (&expr
-> data
.func
, file
, line
);
2939 /* No subexpressions. */
2940 case expr_leased_address
:
2941 case expr_lease_time
:
2944 case expr_const_int
:
2956 free_expression (expr
, MDL
);
2959 int is_dns_expression (expr
)
2960 struct expression
*expr
;
2962 return (expr
-> op
== expr_ns_add
||
2963 expr
-> op
== expr_ns_delete
||
2964 expr
-> op
== expr_ns_exists
||
2965 expr
-> op
== expr_ns_not_exists
);
2968 int is_boolean_expression (expr
)
2969 struct expression
*expr
;
2971 return (expr
-> op
== expr_check
||
2972 expr
-> op
== expr_exists
||
2973 expr
-> op
== expr_variable_exists
||
2974 expr
-> op
== expr_equal
||
2975 expr
-> op
== expr_not_equal
||
2976 expr
-> op
== expr_and
||
2977 expr
-> op
== expr_or
||
2978 expr
-> op
== expr_not
||
2979 expr
-> op
== expr_known
||
2980 expr
-> op
== expr_static
);
2983 int is_data_expression (expr
)
2984 struct expression
*expr
;
2986 return (expr
-> op
== expr_substring
||
2987 expr
-> op
== expr_suffix
||
2988 expr
-> op
== expr_option
||
2989 expr
-> op
== expr_hardware
||
2990 expr
-> op
== expr_const_data
||
2991 expr
-> op
== expr_packet
||
2992 expr
-> op
== expr_concat
||
2993 expr
-> op
== expr_encapsulate
||
2994 expr
-> op
== expr_encode_int8
||
2995 expr
-> op
== expr_encode_int16
||
2996 expr
-> op
== expr_encode_int32
||
2997 expr
-> op
== expr_host_lookup
||
2998 expr
-> op
== expr_binary_to_ascii
||
2999 expr
-> op
== expr_filename
||
3000 expr
-> op
== expr_sname
||
3001 expr
-> op
== expr_reverse
||
3002 expr
-> op
== expr_pick_first_value
||
3003 expr
-> op
== expr_host_decl_name
||
3004 expr
-> op
== expr_leased_address
||
3005 expr
-> op
== expr_config_option
||
3006 expr
-> op
== expr_null
);
3009 int is_numeric_expression (expr
)
3010 struct expression
*expr
;
3012 return (expr
-> op
== expr_extract_int8
||
3013 expr
-> op
== expr_extract_int16
||
3014 expr
-> op
== expr_extract_int32
||
3015 expr
-> op
== expr_const_int
||
3016 expr
-> op
== expr_lease_time
||
3017 expr
-> op
== expr_dns_transaction
||
3018 expr
-> op
== expr_add
||
3019 expr
-> op
== expr_subtract
||
3020 expr
-> op
== expr_multiply
||
3021 expr
-> op
== expr_divide
||
3022 expr
-> op
== expr_remainder
||
3023 expr
-> op
== expr_binary_and
||
3024 expr
-> op
== expr_binary_or
||
3025 expr
-> op
== expr_binary_xor
||
3026 expr
-> op
== expr_client_state
);
3029 int is_compound_expression (expr
)
3030 struct expression
*expr
;
3032 return (expr
-> op
== expr_ns_add
||
3033 expr
-> op
== expr_ns_delete
||
3034 expr
-> op
== expr_ns_exists
||
3035 expr
-> op
== expr_ns_not_exists
||
3036 expr
-> op
== expr_substring
||
3037 expr
-> op
== expr_suffix
||
3038 expr
-> op
== expr_option
||
3039 expr
-> op
== expr_concat
||
3040 expr
-> op
== expr_encode_int8
||
3041 expr
-> op
== expr_encode_int16
||
3042 expr
-> op
== expr_encode_int32
||
3043 expr
-> op
== expr_binary_to_ascii
||
3044 expr
-> op
== expr_reverse
||
3045 expr
-> op
== expr_pick_first_value
||
3046 expr
-> op
== expr_config_option
||
3047 expr
-> op
== expr_extract_int8
||
3048 expr
-> op
== expr_extract_int16
||
3049 expr
-> op
== expr_extract_int32
||
3050 expr
-> op
== expr_dns_transaction
);
3053 static int op_val
PROTO ((enum expr_op
));
3055 static int op_val (op
)
3063 case expr_substring
:
3066 case expr_encapsulate
:
3067 case expr_host_lookup
:
3072 case expr_const_data
:
3073 case expr_extract_int8
:
3074 case expr_extract_int16
:
3075 case expr_extract_int32
:
3076 case expr_encode_int8
:
3077 case expr_encode_int16
:
3078 case expr_encode_int32
:
3079 case expr_const_int
:
3081 case expr_variable_exists
:
3083 case expr_binary_to_ascii
:
3087 case expr_pick_first_value
:
3088 case expr_host_decl_name
:
3089 case expr_config_option
:
3090 case expr_leased_address
:
3091 case expr_lease_time
:
3092 case expr_dns_transaction
:
3094 case expr_variable_reference
:
3096 case expr_ns_delete
:
3097 case expr_ns_exists
:
3098 case expr_ns_not_exists
:
3102 /* XXXDPN: Need to assign sane precedences to these. */
3103 case expr_binary_and
:
3104 case expr_binary_or
:
3105 case expr_binary_xor
:
3106 case expr_client_state
:
3110 case expr_not_equal
:
3123 case expr_remainder
:
3129 int op_precedence (op1
, op2
)
3130 enum expr_op op1
, op2
;
3134 return op_val (op1
) - op_val (op2
);
3137 enum expression_context
expression_context (struct expression
*expr
)
3139 if (is_data_expression (expr
))
3140 return context_data
;
3141 if (is_numeric_expression (expr
))
3142 return context_numeric
;
3143 if (is_boolean_expression (expr
))
3144 return context_boolean
;
3145 if (is_dns_expression (expr
))
3150 enum expression_context
op_context (op
)
3154 /* XXX Why aren't these specific? */
3159 case expr_substring
:
3162 case expr_encapsulate
:
3163 case expr_host_lookup
:
3168 case expr_const_data
:
3169 case expr_extract_int8
:
3170 case expr_extract_int16
:
3171 case expr_extract_int32
:
3172 case expr_encode_int8
:
3173 case expr_encode_int16
:
3174 case expr_encode_int32
:
3175 case expr_const_int
:
3177 case expr_variable_exists
:
3179 case expr_binary_to_ascii
:
3183 case expr_pick_first_value
:
3184 case expr_host_decl_name
:
3185 case expr_config_option
:
3186 case expr_leased_address
:
3187 case expr_lease_time
:
3189 case expr_variable_reference
:
3191 case expr_ns_delete
:
3192 case expr_ns_exists
:
3193 case expr_ns_not_exists
:
3194 case expr_dns_transaction
:
3201 case expr_not_equal
:
3202 return context_data
;
3205 return context_boolean
;
3208 return context_boolean
;
3214 case expr_remainder
:
3215 case expr_binary_and
:
3216 case expr_binary_or
:
3217 case expr_binary_xor
:
3218 case expr_client_state
:
3219 return context_numeric
;
3224 int write_expression (file
, expr
, col
, indent
, firstp
)
3226 struct expression
*expr
;
3231 struct expression
*e
;
3237 /* If this promises to be a fat expression, start a new line. */
3238 if (!firstp
&& is_compound_expression (expr
)) {
3239 indent_spaces (file
, indent
);
3243 switch (expr
-> op
) {
3245 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3249 col
= token_print_indent (file
, col
, indent
, "", "", "check");
3250 col
= token_print_indent_concat (file
, col
, indent
,
3252 expr
-> data
.check
-> name
,
3256 case expr_not_equal
:
3263 col
= write_expression (file
, expr
-> data
.equal
[0],
3265 col
= token_print_indent (file
, col
, indent
, " ", " ", s
);
3266 col
= write_expression (file
, expr
-> data
.equal
[1],
3267 col
, indent
+ 2, 0);
3270 case expr_substring
:
3271 col
= token_print_indent (file
, col
, indent
, "", "",
3273 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3275 col
= write_expression (file
, expr
-> data
.substring
.expr
,
3277 col
= token_print_indent (file
, col
, indent
, "", " ", ",");
3278 col
= write_expression (file
, expr
-> data
.substring
.offset
,
3280 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3281 col
= write_expression (file
, expr
-> data
.substring
.len
,
3283 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3287 col
= token_print_indent (file
, col
, indent
, "", "", "suffix");
3288 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3290 col
= write_expression (file
, expr
-> data
.suffix
.expr
,
3292 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3293 col
= write_expression (file
, expr
-> data
.suffix
.len
,
3295 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3300 col
= token_print_indent (file
, col
, indent
, "", "",
3302 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3306 col
= write_expression (file
, e
-> data
.concat
[0],
3309 if (!e
-> data
.concat
[1])
3311 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3312 if (e
-> data
.concat
[1] -> op
== expr_concat
) {
3313 e
= e
-> data
.concat
[1];
3316 col
= write_expression (file
, e
-> data
.concat
[1],
3319 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3322 case expr_host_lookup
:
3323 col
= token_print_indent (file
, col
, indent
, "", "",
3325 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3326 col
= token_print_indent_concat
3327 (file
, col
, indent
, "", "",
3328 "\"", expr
-> data
.host_lookup
-> hostname
, "\"",
3330 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3349 case expr_remainder
:
3353 case expr_binary_and
:
3357 case expr_binary_or
:
3361 case expr_binary_xor
:
3374 col
= token_print_indent (file
, col
, indent
, "", " ", "not");
3375 col
= write_expression (file
,
3376 expr
-> data
.not, col
, indent
+ 2, 1);
3383 col
= token_print_indent (file
, col
, indent
, "", "", s
);
3385 if (expr
-> data
.option
-> universe
!= &dhcp_universe
) {
3386 col
= token_print_indent (file
, col
, indent
,
3388 (expr
-> data
.option
->
3390 col
= token_print_indent (file
, col
, indent
, "", "",
3392 col
= token_print_indent (file
, col
, indent
, "", "",
3393 expr
-> data
.option
-> name
);
3395 col
= token_print_indent (file
, col
, indent
, " ", "",
3396 expr
-> data
.option
-> name
);
3401 col
= token_print_indent (file
, col
, indent
, "", "",
3406 col
= token_print_indent (file
, col
, indent
, "", "",
3408 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3410 col
= write_expression (file
, expr
-> data
.packet
.offset
,
3412 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3413 col
= write_expression (file
, expr
-> data
.packet
.len
,
3415 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3418 case expr_const_data
:
3419 col
= token_indent_data_string (file
, col
, indent
, "", "",
3420 &expr
-> data
.const_data
);
3423 case expr_extract_int8
:
3426 col
= token_print_indent (file
, col
, indent
, "", "",
3428 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3430 col
= write_expression (file
, expr
-> data
.extract_int
,
3432 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3433 sprintf (obuf
, "%d", width
);
3434 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3435 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3438 case expr_extract_int16
:
3442 case expr_extract_int32
:
3446 case expr_encode_int8
:
3449 col
= token_print_indent (file
, col
, indent
, "", "",
3451 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3453 col
= write_expression (file
, expr
-> data
.extract_int
,
3455 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3456 sprintf (obuf
, "%d", width
);
3457 col
= token_print_indent (file
, col
, scol
, " ", "", obuf
);
3458 col
= token_print_indent (file
, col
, indent
, "", "",
3462 case expr_encode_int16
:
3466 case expr_encode_int32
:
3470 case expr_const_int
:
3471 sprintf (obuf
, "%lu", expr
-> data
.const_int
);
3472 col
= token_print_indent (file
, col
, indent
, "", "", obuf
);
3477 goto print_option_name
;
3479 case expr_encapsulate
:
3480 col
= token_print_indent (file
, col
, indent
, "", "",
3482 col
= token_indent_data_string (file
, col
, indent
, " ", "",
3483 &expr
-> data
.encapsulate
);
3487 col
= token_print_indent (file
, col
, indent
, "", "", "known");
3491 col
= token_print_indent (file
, col
, indent
, "", "",
3493 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3495 col
= write_expression (file
, expr
-> data
.reverse
.width
,
3497 col
= token_print_indent (file
, col
, scol
, "", " ", ",");
3498 col
= write_expression (file
, expr
-> data
.reverse
.buffer
,
3500 col
= token_print_indent (file
, col
, indent
, "", "",
3504 case expr_leased_address
:
3505 col
= token_print_indent (file
, col
, indent
, "", "",
3509 case expr_client_state
:
3510 col
= token_print_indent (file
, col
, indent
, "", "",
3514 case expr_binary_to_ascii
:
3515 col
= token_print_indent (file
, col
, indent
, "", "",
3517 col
= token_print_indent (file
, col
, indent
, " ", "",
3520 col
= write_expression (file
, expr
-> data
.b2a
.base
,
3522 col
= token_print_indent (file
, col
, scol
, "", " ",
3524 col
= write_expression (file
, expr
-> data
.b2a
.width
,
3526 col
= token_print_indent (file
, col
, scol
, "", " ",
3528 col
= write_expression (file
, expr
-> data
.b2a
.seperator
,
3530 col
= token_print_indent (file
, col
, scol
, "", " ",
3532 col
= write_expression (file
, expr
-> data
.b2a
.buffer
,
3534 col
= token_print_indent (file
, col
, indent
, "", "",
3538 case expr_config_option
:
3539 s
= "config-option";
3540 goto print_option_name
;
3542 case expr_host_decl_name
:
3543 col
= token_print_indent (file
, col
, indent
, "", "",
3547 case expr_pick_first_value
:
3549 col
= token_print_indent (file
, col
, indent
, "", "",
3551 col
= token_print_indent (file
, col
, indent
, " ", "",
3556 col
= write_expression (file
,
3557 e
-> data
.pick_first_value
.car
,
3560 /* We're being very lisp-like right now - instead of
3561 representing this expression as (first middle . last) we're
3562 representing it as (first middle last), which means that the
3563 tail cdr is always nil. Apologies to non-wisp-lizards - may
3564 this obscure way of describing the problem motivate you to
3565 learn more about the one true computing language. */
3566 if (!e
-> data
.pick_first_value
.cdr
)
3568 col
= token_print_indent (file
, col
, scol
, "", " ",
3570 if (e
-> data
.pick_first_value
.cdr
-> op
==
3571 expr_pick_first_value
) {
3572 e
= e
-> data
.pick_first_value
.cdr
;
3575 col
= write_expression (file
,
3576 e
-> data
.pick_first_value
.cdr
,
3579 col
= token_print_indent (file
, col
, indent
, "", "",
3583 case expr_lease_time
:
3584 col
= token_print_indent (file
, col
, indent
, "", "",
3588 case expr_dns_transaction
:
3589 col
= token_print_indent (file
, col
, indent
, "", "",
3591 col
= token_print_indent (file
, col
, indent
, " ", "",
3595 e
&& e
-> op
== expr_dns_transaction
;
3596 e
= e
-> data
.dns_transaction
.cdr
) {
3602 col
= write_expression (file
,
3603 e
-> data
.dns_transaction
.car
,
3605 if (e
-> data
.dns_transaction
.cdr
)
3606 col
= token_print_indent (file
, col
, scol
,
3610 col
= write_expression (file
, e
, col
, scol
, 0);
3611 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3615 col
= token_print_indent (file
, col
, indent
, "", "",
3617 col
= token_print_indent (file
, col
, indent
, " ", "",
3620 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3621 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3622 col
= token_print_indent (file
, col
, scol
, "", " ",
3624 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3625 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3626 col
= token_print_indent (file
, col
, scol
, "", " ",
3628 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3630 col
= token_print_indent (file
, col
, scol
, "", " ",
3632 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3634 col
= token_print_indent (file
, col
, scol
, "", " ",
3636 col
= write_expression (file
, expr
-> data
.ns_add
.ttl
,
3638 col
= token_print_indent (file
, col
, indent
, "", "",
3642 case expr_ns_delete
:
3643 col
= token_print_indent (file
, col
, indent
, "", "",
3645 col
= token_print_indent (file
, col
, indent
, " ", "",
3649 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrclass
);
3650 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3651 col
= token_print_indent (file
, col
, scol
, "", " ",
3653 sprintf (obuf
, "%d", expr
-> data
.ns_add
.rrtype
);
3654 col
= token_print_indent (file
, col
, scol
, "", "", obuf
);
3655 col
= token_print_indent (file
, col
, scol
, "", " ",
3657 col
= write_expression (file
, expr
-> data
.ns_add
.rrname
,
3659 col
= token_print_indent (file
, col
, scol
, "", " ",
3661 col
= write_expression (file
, expr
-> data
.ns_add
.rrdata
,
3663 col
= token_print_indent (file
, col
, indent
, "", "",
3667 case expr_ns_exists
:
3668 col
= token_print_indent (file
, col
, indent
, "", "",
3670 col
= token_print_indent (file
, col
, indent
, " ", "",
3672 goto finish_ns_small
;
3674 case expr_ns_not_exists
:
3675 col
= token_print_indent (file
, col
, indent
, "", "",
3677 col
= token_print_indent (file
, col
, indent
, " ", "",
3679 goto finish_ns_small
;
3682 col
= token_print_indent (file
, col
, indent
, "", "",
3687 col
= token_print_indent (file
, col
, indent
, "", "", "null");
3690 case expr_variable_reference
:
3691 col
= token_print_indent (file
, indent
, indent
, "", "",
3692 expr
-> data
.variable
);
3695 case expr_variable_exists
:
3696 col
= token_print_indent (file
, indent
, indent
, "", "",
3698 col
= token_print_indent (file
, col
, indent
, " ", "", "(");
3699 col
= token_print_indent (file
, col
, indent
, "", "",
3700 expr
-> data
.variable
);
3701 col
= token_print_indent (file
, col
, indent
, "", "", ")");
3705 log_fatal ("invalid expression type in print_expression: %d",
3711 struct binding
*find_binding (struct binding_scope
*scope
, const char *name
)
3714 struct binding_scope
*s
;
3716 for (s
= scope
; s
; s
= s
-> outer
) {
3717 for (bp
= s
-> bindings
; bp
; bp
= bp
-> next
) {
3718 if (!strcasecmp (name
, bp
-> name
)) {
3723 return (struct binding
*)0;
3726 int free_bindings (struct binding_scope
*scope
, const char *file
, int line
)
3728 struct binding
*bp
, *next
;
3730 for (bp
= scope
-> bindings
; bp
; bp
= next
) {
3733 dfree (bp
-> name
, file
, line
);
3735 binding_value_dereference (&bp
-> value
, file
, line
);
3736 dfree (bp
, file
, line
);
3738 scope
-> bindings
= (struct binding
*)0;
3742 int binding_scope_dereference (ptr
, file
, line
)
3743 struct binding_scope
**ptr
;
3748 struct binding_scope
*binding_scope
;
3750 if (!ptr
|| !*ptr
) {
3751 log_error ("%s(%d): null pointer", file
, line
);
3752 #if defined (POINTER_DEBUG)
3759 binding_scope
= *ptr
;
3760 *ptr
= (struct binding_scope
*)0;
3761 --binding_scope
-> refcnt
;
3762 rc_register (file
, line
, ptr
,
3763 binding_scope
, binding_scope
-> refcnt
, 1, RC_MISC
);
3764 if (binding_scope
-> refcnt
> 0)
3767 if (binding_scope
-> refcnt
< 0) {
3768 log_error ("%s(%d): negative refcnt!", file
, line
);
3769 #if defined (DEBUG_RC_HISTORY)
3770 dump_rc_history (binding_scope
);
3772 #if defined (POINTER_DEBUG)
3779 free_bindings (binding_scope
, file
, line
);
3780 if (binding_scope
-> outer
)
3781 binding_scope_dereference (&binding_scope
-> outer
, MDL
);
3782 dfree (binding_scope
, file
, line
);
3786 int fundef_dereference (ptr
, file
, line
)
3787 struct fundef
**ptr
;
3791 struct fundef
*bp
= *ptr
;
3792 struct string_list
*sp
, *next
;
3795 log_error ("%s(%d): null pointer", file
, line
);
3796 #if defined (POINTER_DEBUG)
3804 log_error ("%s(%d): null pointer", file
, line
);
3805 #if defined (POINTER_DEBUG)
3813 rc_register (file
, line
, ptr
, bp
, bp
-> refcnt
, 1, RC_MISC
);
3814 if (bp
-> refcnt
< 0) {
3815 log_error ("%s(%d): negative refcnt!", file
, line
);
3816 #if defined (DEBUG_RC_HISTORY)
3817 dump_rc_history (bp
);
3819 #if defined (POINTER_DEBUG)
3825 if (!bp
-> refcnt
) {
3826 for (sp
= bp
-> args
; sp
; sp
= next
) {
3828 dfree (sp
, file
, line
);
3830 if (bp
-> statements
)
3831 executable_statement_dereference (&bp
-> statements
,
3833 dfree (bp
, file
, line
);
3835 *ptr
= (struct fundef
*)0;
3839 #if defined (NOTYET) /* Post 3.0 final. */
3840 int data_subexpression_length (int *rv
,
3841 struct expression
*expr
)
3843 int crhs
, clhs
, llhs
, lrhs
;
3844 switch (expr
-> op
) {
3845 case expr_substring
:
3846 if (expr
-> data
.substring
.len
&&
3847 expr
-> data
.substring
.len
-> op
== expr_const_int
) {
3849 (int)expr
-> data
.substring
.len
-> data
.const_int
);
3856 if (expr
-> data
.suffix
.len
&&
3857 expr
-> data
.suffix
.len
-> op
== expr_const_int
) {
3859 (int)expr
-> data
.suffix
.len
-> data
.const_int
);
3865 clhs
= data_subexpression_length (&llhs
,
3866 expr
-> data
.concat
[0]);
3867 crhs
= data_subexpression_length (&lrhs
,
3868 expr
-> data
.concat
[1]);
3869 if (crhs
== 0 || clhs
== 0)
3878 case expr_const_data
:
3879 *rv
= expr
-> data
.const_data
.len
;
3883 return data_subexpression_length (rv
,
3884 expr
-> data
.reverse
.buffer
);
3886 case expr_leased_address
:
3887 case expr_lease_time
:
3891 case expr_pick_first_value
:
3892 clhs
= data_subexpression_length (&llhs
,
3893 expr
-> data
.concat
[0]);
3894 crhs
= data_subexpression_length (&lrhs
,
3895 expr
-> data
.concat
[1]);
3896 if (crhs
== 0 || clhs
== 0)
3904 case expr_binary_to_ascii
:
3905 case expr_config_option
:
3906 case expr_host_decl_name
:
3907 case expr_encapsulate
:
3910 case expr_host_lookup
:
3919 case expr_extract_int8
:
3920 case expr_extract_int16
:
3921 case expr_extract_int32
:
3922 case expr_encode_int8
:
3923 case expr_encode_int16
:
3924 case expr_encode_int32
:
3925 case expr_const_int
:
3928 case expr_dns_transaction
:
3931 case expr_ns_delete
:
3932 case expr_ns_exists
:
3933 case expr_ns_not_exists
:
3934 case expr_not_equal
:
3936 case expr_variable_exists
:
3937 case expr_variable_reference
:
3945 case expr_remainder
:
3946 case expr_binary_and
:
3947 case expr_binary_or
:
3948 case expr_binary_xor
:
3949 case expr_client_state
:
3955 int expr_valid_for_context (struct expression
*expr
,
3956 enum expression_context context
)
3958 /* We don't know at parse time what type of value a function may
3959 return, so we can't flag an error on it. */
3960 if (expr
-> op
== expr_funcall
||
3961 expr
-> op
== expr_variable_reference
)
3968 case context_boolean
:
3969 if (is_boolean_expression (expr
))
3974 if (is_data_expression (expr
))
3978 case context_numeric
:
3979 if (is_numeric_expression (expr
))
3984 if (is_dns_expression (expr
)) {
3989 case context_data_or_numeric
:
3990 if (is_numeric_expression (expr
) ||
3991 is_data_expression (expr
)) {
3996 case context_function
:
3997 if (expr
-> op
== expr_function
)
4005 struct binding
*create_binding (struct binding_scope
**scope
, const char *name
)
4007 struct binding
*binding
;
4010 if (!binding_scope_allocate (scope
, MDL
))
4011 return (struct binding
*)0;
4014 binding
= find_binding (*scope
, name
);
4016 binding
= dmalloc (sizeof *binding
, MDL
);
4018 return (struct binding
*)0;
4020 memset (binding
, 0, sizeof *binding
);
4021 binding
-> name
= dmalloc (strlen (name
) + 1, MDL
);
4022 if (!binding
-> name
) {
4023 dfree (binding
, MDL
);
4024 return (struct binding
*)0;
4026 strcpy (binding
-> name
, name
);
4028 binding
-> next
= (*scope
) -> bindings
;
4029 (*scope
) -> bindings
= binding
;
4036 int bind_ds_value (struct binding_scope
**scope
,
4038 struct data_string
*value
)
4040 struct binding
*binding
;
4042 binding
= create_binding (scope
, name
);
4046 if (binding
-> value
)
4047 binding_value_dereference (&binding
-> value
, MDL
);
4049 if (!binding_value_allocate (&binding
-> value
, MDL
))
4052 data_string_copy (&binding
-> value
-> value
.data
, value
, MDL
);
4053 binding
-> value
-> type
= binding_data
;
4059 int find_bound_string (struct data_string
*value
,
4060 struct binding_scope
*scope
,
4063 struct binding
*binding
;
4065 binding
= find_binding (scope
, name
);
4067 !binding
-> value
||
4068 binding
-> value
-> type
!= binding_data
)
4071 if (binding
-> value
-> value
.data
.terminated
) {
4072 data_string_copy (value
, &binding
-> value
-> value
.data
, MDL
);
4074 buffer_allocate (&value
-> buffer
,
4075 binding
-> value
-> value
.data
.len
,
4077 if (!value
-> buffer
)
4080 memcpy (value
-> buffer
-> data
,
4081 binding
-> value
-> value
.data
.data
,
4082 binding
-> value
-> value
.data
.len
);
4083 value
-> data
= value
-> buffer
-> data
;
4084 value
-> len
= binding
-> value
-> value
.data
.len
;
4090 int unset (struct binding_scope
*scope
, const char *name
)
4092 struct binding
*binding
;
4094 binding
= find_binding (scope
, name
);
4096 if (binding
-> value
)
4097 binding_value_dereference
4098 (&binding
-> value
, MDL
);
4104 /* vim: set tabstop=8: */