3
Routines for manipulating parse trees... */
6
* Copyright (c) 2004-2007 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
#include <omapip/omapip_p.h>
44
struct binding_scope *global_scope;
46
static int do_host_lookup PROTO ((struct data_string *,
47
struct dns_host_entry *));
50
struct __res_state resolver_state;
51
int resolver_inited = 0;
54
#define DS_SPRINTF_SIZE 128
57
* If we are using a data_string structure to hold a NUL-terminated
58
* ASCII string, this function can be used to append a printf-formatted
59
* string to the end of it. The data_string structure will be resized to
60
* be big enough to hold the new string.
62
* If the append works, then 1 is returned.
64
* If it is not possible to allocate a buffer big enough to hold the
65
* new value, then the old data_string is unchanged, and 0 is returned.
68
data_string_sprintfa(struct data_string *ds, const char *fmt, ...) {
74
struct buffer *tmp_buffer;
77
* If the data_string is empty, then initialize it.
79
if (ds->data == NULL) {
80
/* INSIST(ds.buffer == NULL); */
81
if (!buffer_allocate(&ds->buffer, DS_SPRINTF_SIZE, MDL)) {
84
ds->data = ds->buffer->data;
85
ds->len = DS_SPRINTF_SIZE;
86
*((char *)ds->data) = '\0';
90
* Get the length of the string, and figure out how much space
93
cur_strlen = strlen((char *)ds->data);
94
max = ds->len - cur_strlen;
97
* Use vsnprintf(), which won't write past our space, but will
98
* tell us how much space it wants.
101
vsnprintf_ret = vsnprintf((char *)ds->data+cur_strlen, max, fmt, args);
103
/* INSIST(vsnprintf_ret >= 0); */
106
* If our buffer is not big enough, we need a new buffer.
108
if (vsnprintf_ret >= max) {
110
* Figure out a size big enough.
112
new_len = ds->len * 2;
113
while (new_len <= cur_strlen + vsnprintf_ret) {
118
* Create a new buffer and fill it.
121
if (!buffer_allocate(&tmp_buffer, new_len, MDL)) {
123
* If we can't create a big enough buffer,
124
* we should remove any truncated output that we had.
126
*((char *)ds->data+cur_strlen) = '\0';
130
memcpy(tmp_buffer->data, ds->data, cur_strlen);
132
/* Rerun the vsprintf. */
134
vsprintf((char *)tmp_buffer->data + cur_strlen, fmt, args);
138
* Replace our old buffer with the new buffer.
140
buffer_dereference(&ds->buffer, MDL);
141
buffer_reference(&ds->buffer, tmp_buffer, MDL);
142
buffer_dereference(&tmp_buffer, MDL);
143
ds->data = ds->buffer->data;
153
pair foo = (pair)dmalloc (sizeof *foo, MDL);
155
log_fatal ("no memory for cons.");
161
int make_const_option_cache (oc, buffer, data, len, option, file, line)
162
struct option_cache **oc;
163
struct buffer **buffer;
166
struct option *option;
176
bp = (struct buffer *)0;
177
if (!buffer_allocate (&bp, len, file, line)) {
178
log_error ("%s(%d): can't allocate buffer.",
184
if (!option_cache_allocate (oc, file, line)) {
185
log_error ("%s(%d): can't allocate option cache.", file, line);
186
buffer_dereference (&bp, file, line);
190
(*oc) -> data.len = len;
191
(*oc) -> data.buffer = bp;
192
(*oc) -> data.data = &bp -> data [0];
193
(*oc) -> data.terminated = 0;
195
memcpy (&bp -> data [0], data, len);
196
option_reference(&((*oc)->option), option, MDL);
200
int make_host_lookup (expr, name)
201
struct expression **expr;
204
if (!expression_allocate (expr, MDL)) {
205
log_error ("No memory for host lookup tree node.");
208
(*expr) -> op = expr_host_lookup;
209
if (!enter_dns_host (&((*expr) -> data.host_lookup), name)) {
210
expression_dereference (expr, MDL);
216
int enter_dns_host (dh, name)
217
struct dns_host_entry **dh;
220
/* XXX This should really keep a hash table of hostnames
221
XXX and just add a new reference to a hostname that
222
XXX already exists, if possible, rather than creating
223
XXX a new structure. */
224
if (!dns_host_entry_allocate (dh, name, MDL)) {
225
log_error ("Can't allocate space for new host.");
231
int make_const_data (struct expression **expr, const unsigned char *data,
232
unsigned len, int terminated, int allocate,
233
const char *file, int line)
235
struct expression *nt;
237
if (!expression_allocate (expr, file, line)) {
238
log_error ("No memory for make_const_data tree node.");
245
if (!buffer_allocate (&nt -> data.const_data.buffer,
246
len + terminated, file, line)) {
247
log_error ("Can't allocate const_data buffer");
248
expression_dereference (expr, file, line);
251
nt -> data.const_data.data =
252
&nt -> data.const_data.buffer -> data [0];
253
memcpy (nt -> data.const_data.buffer -> data,
254
data, len + terminated);
256
nt -> data.const_data.data = data;
257
nt -> data.const_data.terminated = terminated;
259
nt -> data.const_data.data = 0;
261
nt -> op = expr_const_data;
262
nt -> data.const_data.len = len;
266
int make_const_int (expr, val)
267
struct expression **expr;
270
if (!expression_allocate (expr, MDL)) {
271
log_error ("No memory for make_const_int tree node.");
275
(*expr) -> op = expr_const_int;
276
(*expr) -> data.const_int = val;
280
int make_concat (expr, left, right)
281
struct expression **expr;
282
struct expression *left, *right;
284
/* If we're concatenating a null tree to a non-null tree, just
285
return the non-null tree; if both trees are null, return
290
expression_reference (expr, right, MDL);
294
expression_reference (expr, left, MDL);
298
/* Otherwise, allocate a new node to concatenate the two. */
299
if (!expression_allocate (expr, MDL)) {
300
log_error ("No memory for concatenation expression node.");
304
(*expr) -> op = expr_concat;
305
expression_reference (&(*expr) -> data.concat [0], left, MDL);
306
expression_reference (&(*expr) -> data.concat [1], right, MDL);
310
int make_encapsulation (expr, name)
311
struct expression **expr;
312
struct data_string *name;
314
/* Allocate a new node to store the encapsulation. */
315
if (!expression_allocate (expr, MDL)) {
316
log_error ("No memory for encapsulation expression node.");
320
(*expr) -> op = expr_encapsulate;
321
data_string_copy (&(*expr) -> data.encapsulate, name, MDL);
325
int make_substring (new, expr, offset, length)
326
struct expression **new;
327
struct expression *expr;
328
struct expression *offset;
329
struct expression *length;
331
/* Allocate an expression node to compute the substring. */
332
if (!expression_allocate (new, MDL)) {
333
log_error ("no memory for substring expression.");
336
(*new) -> op = expr_substring;
337
expression_reference (&(*new) -> data.substring.expr, expr, MDL);
338
expression_reference (&(*new) -> data.substring.offset, offset, MDL);
339
expression_reference (&(*new) -> data.substring.len, length, MDL);
343
int make_limit (new, expr, limit)
344
struct expression **new;
345
struct expression *expr;
348
/* Allocate a node to enforce a limit on evaluation. */
349
if (!expression_allocate (new, MDL))
350
log_error ("no memory for limit expression");
351
(*new) -> op = expr_substring;
352
expression_reference (&(*new) -> data.substring.expr, expr, MDL);
354
/* Offset is a constant 0. */
355
if (!expression_allocate (&(*new) -> data.substring.offset, MDL)) {
356
log_error ("no memory for limit offset expression");
357
expression_dereference (new, MDL);
360
(*new) -> data.substring.offset -> op = expr_const_int;
361
(*new) -> data.substring.offset -> data.const_int = 0;
363
/* Length is a constant: the specified limit. */
364
if (!expression_allocate (&(*new) -> data.substring.len, MDL)) {
365
log_error ("no memory for limit length expression");
366
expression_dereference (new, MDL);
369
(*new) -> data.substring.len -> op = expr_const_int;
370
(*new) -> data.substring.len -> data.const_int = limit;
375
int option_cache (struct option_cache **oc, struct data_string *dp,
376
struct expression *expr, struct option *option,
377
const char *file, int line)
379
if (!option_cache_allocate (oc, file, line))
382
data_string_copy (&(*oc) -> data, dp, file, line);
384
expression_reference (&(*oc) -> expression, expr, file, line);
385
option_reference(&(*oc)->option, option, MDL);
389
int make_let (result, name)
390
struct executable_statement **result;
393
if (!(executable_statement_allocate (result, MDL)))
396
(*result) -> op = let_statement;
397
(*result) -> data.let.name = dmalloc (strlen (name) + 1, MDL);
398
if (!(*result) -> data.let.name) {
399
executable_statement_dereference (result, MDL);
402
strcpy ((*result) -> data.let.name, name);
406
static int do_host_lookup (result, dns)
407
struct data_string *result;
408
struct dns_host_entry *dns;
415
log_debug ("time: now = %d dns = %d diff = %d",
416
cur_time, dns -> timeout, cur_time - dns -> timeout);
419
/* If the record hasn't timed out, just copy the data and return. */
420
if (cur_time <= dns -> timeout) {
422
log_debug ("easy copy: %d %s",
425
? inet_ntoa (*(struct in_addr *)(dns -> data.data))
428
data_string_copy (result, &dns -> data, MDL);
432
log_debug ("Looking up %s", dns -> hostname);
435
/* Otherwise, look it up... */
436
h = gethostbyname (dns -> hostname);
442
log_error ("%s: host unknown.", dns -> hostname);
446
log_error ("%s: temporary name server failure",
450
log_error ("%s: name server failed", dns -> hostname);
453
log_error ("%s: no A record associated with address",
456
#endif /* !NO_H_ERRNO */
458
/* Okay to try again after a minute. */
459
dns -> timeout = cur_time + 60;
460
data_string_forget (&dns -> data, MDL);
465
log_debug ("Lookup succeeded; first address is %s",
466
inet_ntoa (h -> h_addr_list [0]));
469
/* Count the number of addresses we got... */
470
for (count = 0; h -> h_addr_list [count]; count++)
473
/* Dereference the old data, if any. */
474
data_string_forget (&dns -> data, MDL);
476
/* Do we need to allocate more memory? */
477
new_len = count * h -> h_length;
478
if (!buffer_allocate (&dns -> data.buffer, new_len, MDL))
480
log_error ("No memory for %s.", dns -> hostname);
484
dns -> data.data = &dns -> data.buffer -> data [0];
485
dns -> data.len = new_len;
486
dns -> data.terminated = 0;
488
/* Addresses are conveniently stored one to the buffer, so we
489
have to copy them out one at a time... :'( */
490
for (i = 0; i < count; i++) {
491
memcpy (&dns -> data.buffer -> data [h -> h_length * i],
492
h -> h_addr_list [i], (unsigned)(h -> h_length));
495
log_debug ("dns -> data: %x h -> h_addr_list [0]: %x",
496
*(int *)(dns -> buffer), h -> h_addr_list [0]);
499
/* XXX Set the timeout for an hour from now.
500
XXX This should really use the time on the DNS reply. */
501
dns -> timeout = cur_time + 3600;
504
log_debug ("hard copy: %d %s", dns -> data.len,
506
? inet_ntoa (*(struct in_addr *)(dns -> data.data)) : 0));
508
data_string_copy (result, &dns -> data, MDL);
512
int evaluate_expression (result, packet, lease, client_state,
513
in_options, cfg_options, scope, expr, file, line)
514
struct binding_value **result;
515
struct packet *packet;
517
struct client_state *client_state;
518
struct option_state *in_options;
519
struct option_state *cfg_options;
520
struct binding_scope **scope;
521
struct expression *expr;
525
struct binding_value *bv;
527
struct binding *binding;
529
bv = (struct binding_value *)0;
531
if (expr -> op == expr_variable_reference) {
532
if (!scope || !*scope)
535
binding = find_binding (*scope, expr -> data.variable);
537
if (binding && binding -> value) {
539
binding_value_reference (result,
545
} else if (expr -> op == expr_funcall) {
546
struct string_list *s;
547
struct expression *arg;
548
struct binding_scope *ns;
551
if (!scope || !*scope) {
552
log_error ("%s: no such function.",
553
expr -> data.funcall.name);
557
binding = find_binding (*scope, expr -> data.funcall.name);
559
if (!binding || !binding -> value) {
560
log_error ("%s: no such function.",
561
expr -> data.funcall.name);
564
if (binding -> value -> type != binding_function) {
565
log_error ("%s: not a function.",
566
expr -> data.funcall.name);
570
/* Create a new binding scope in which to define
571
the arguments to the function. */
572
ns = (struct binding_scope *)0;
573
if (!binding_scope_allocate (&ns, MDL)) {
574
log_error ("%s: can't allocate argument scope.",
575
expr -> data.funcall.name);
579
arg = expr -> data.funcall.arglist;
580
s = binding -> value -> value.fundef -> args;
582
nb = dmalloc (sizeof *nb, MDL);
585
binding_scope_dereference (&ns, MDL);
588
memset (nb, 0, sizeof *nb);
589
nb -> name = dmalloc (strlen (s -> string) + 1,
592
strcpy (nb -> name, s -> string);
595
nb = (struct binding *)0;
599
evaluate_expression (&nb -> value, packet, lease,
601
in_options, cfg_options, scope,
602
arg -> data.arg.val, file, line);
603
nb -> next = ns -> bindings;
605
arg = arg -> data.arg.next;
609
log_error ("%s: too many arguments.",
610
expr -> data.funcall.name);
611
binding_scope_dereference (&ns, MDL);
615
log_error ("%s: too few arguments.",
616
expr -> data.funcall.name);
617
binding_scope_dereference (&ns, MDL);
622
binding_scope_reference (&ns -> outer, *scope, MDL);
624
status = (execute_statements
626
lease, client_state, in_options, cfg_options, &ns,
627
binding -> value -> value.fundef -> statements));
628
binding_scope_dereference (&ns, MDL);
632
} else if (is_boolean_expression (expr)) {
633
if (!binding_value_allocate (&bv, MDL))
635
bv -> type = binding_boolean;
636
status = (evaluate_boolean_expression
637
(&bv -> value.boolean, packet, lease, client_state,
638
in_options, cfg_options, scope, expr));
639
} else if (is_numeric_expression (expr)) {
640
if (!binding_value_allocate (&bv, MDL))
642
bv -> type = binding_numeric;
643
status = (evaluate_numeric_expression
644
(&bv -> value.intval, packet, lease, client_state,
645
in_options, cfg_options, scope, expr));
646
} else if (is_data_expression (expr)) {
647
if (!binding_value_allocate (&bv, MDL))
649
bv -> type = binding_data;
650
status = (evaluate_data_expression
651
(&bv -> value.data, packet, lease, client_state,
652
in_options, cfg_options, scope, expr, MDL));
653
} else if (is_dns_expression (expr)) {
654
#if defined (NSUPDATE)
655
if (!binding_value_allocate (&bv, MDL))
657
bv -> type = binding_dns;
658
status = (evaluate_dns_expression
659
(&bv -> value.dns, packet, lease, client_state,
660
in_options, cfg_options, scope, expr));
663
log_error ("%s: invalid expression type: %d",
664
"evaluate_expression", expr -> op);
667
if (result && status)
668
binding_value_reference (result, bv, file, line);
669
binding_value_dereference (&bv, MDL);
674
int binding_value_dereference (struct binding_value **v,
675
const char *file, int line)
677
struct binding_value *bv = *v;
679
*v = (struct binding_value *)0;
681
/* Decrement the reference count. If it's nonzero, we're
684
rc_register (file, line, v, bv, bv -> refcnt, 1, RC_MISC);
685
if (bv -> refcnt > 0)
687
if (bv -> refcnt < 0) {
688
log_error ("%s(%d): negative refcnt!", file, line);
689
#if defined (DEBUG_RC_HISTORY)
690
dump_rc_history (bv);
692
#if defined (POINTER_DEBUG)
699
switch (bv -> type) {
700
case binding_boolean:
701
case binding_numeric:
704
if (bv -> value.data.buffer)
705
data_string_forget (&bv -> value.data, file, line);
708
#if defined (NSUPDATE)
709
if (bv -> value.dns) {
710
if (bv -> value.dns -> r_data) {
711
dfree (bv -> value.dns -> r_data_ephem, MDL);
712
bv -> value.dns -> r_data = (unsigned char *)0;
713
bv -> value.dns -> r_data_ephem =
716
minires_freeupdrec (bv -> value.dns);
721
log_error ("%s(%d): invalid binding type: %d",
722
file, line, bv -> type);
725
free_binding_value(bv, file, line);
729
#if defined (NSUPDATE)
730
int evaluate_dns_expression (result, packet, lease, client_state, in_options,
731
cfg_options, scope, expr)
733
struct packet *packet;
735
struct client_state *client_state;
736
struct option_state *in_options;
737
struct option_state *cfg_options;
738
struct binding_scope **scope;
739
struct expression *expr;
741
unsigned long ttl = 0;
743
struct data_string name, data;
746
if (!result || *result) {
747
log_error ("evaluate_dns_expression called with non-null %s",
749
#if defined (POINTER_DEBUG)
756
switch (expr -> op) {
757
#if defined (NSUPDATE)
759
r0 = evaluate_numeric_expression (&ttl, packet, lease,
761
in_options, cfg_options,
763
expr -> data.ns_add.ttl);
770
case expr_ns_not_exists:
773
memset (&name, 0, sizeof name);
774
r1 = evaluate_data_expression (&name, packet, lease,
776
in_options, cfg_options, scope,
777
expr -> data.ns_add.rrname,
780
/* The result of the evaluation may or may not
781
be NUL-terminated, but we need it
782
terminated for sure, so we have to allocate
783
a buffer and terminate it. */
784
tname = dmalloc (name.len + 1, MDL);
788
data_string_forget (&name, MDL);
790
memcpy (tname, name.data, name.len);
791
tname [name.len] = 0;
792
memset (&data, 0, sizeof data);
793
r2 = evaluate_data_expression
794
(&data, packet, lease, client_state,
795
in_options, cfg_options, scope,
796
expr -> data.ns_add.rrdata, MDL);
802
if (r0 && r1 && (r2 || expr -> op != expr_ns_add)) {
803
*result = minires_mkupdrec (((expr -> op == expr_ns_add ||
804
expr -> op == expr_ns_delete)
805
? S_UPDATE : S_PREREQ),
807
expr -> data.ns_add.rrclass,
808
expr -> data.ns_add.rrtype,
813
data_string_forget (&data, MDL);
818
/* As a special case, if we get exactly
819
four bytes of data, it's an IP address
820
represented as a 32-bit quantity, which
821
is actually what we *should* be getting
822
here. Because res_mkupdrec is currently
823
broken and expects a dotted quad, convert
824
it. This should be fixed when the new
825
resolver is merged. */
827
(*result) -> r_data_ephem =
829
if (!(*result) -> r_data_ephem)
831
(*result) -> r_data =
832
(*result) -> r_data_ephem;
833
/*%Audit% 16 bytes max. %2004.06.17,Safe%*/
834
sprintf ((char *)(*result) -> r_data_ephem,
836
data.data [0] & 0xff,
837
data.data [1] & 0xff,
838
data.data [2] & 0xff,
839
data.data [3] & 0xff);
840
(*result) -> r_size =
841
strlen ((const char *)
842
(*result) -> r_data);
844
(*result) -> r_size = data.len;
845
(*result) -> r_data_ephem =
846
dmalloc (data.len, MDL);
847
if (!(*result) -> r_data_ephem) {
848
dpngood: /* double plus ungood. */
849
minires_freeupdrec (*result);
853
(*result) -> r_data =
854
(*result) -> r_data_ephem;
855
memcpy ((*result) -> r_data_ephem,
856
data.data, data.len);
859
(*result) -> r_data = 0;
860
(*result) -> r_size = 0;
862
switch (expr -> op) {
864
(*result) -> r_opcode = ADD;
867
(*result) -> r_opcode = DELETE;
870
(*result) -> r_opcode = YXRRSET;
872
case expr_ns_not_exists:
873
(*result) -> r_opcode = NXRRSET;
876
/* Can't happen, but satisfy gcc. */
883
data_string_forget (&name, MDL);
887
data_string_forget (&data, MDL);
888
/* One flaw in the thinking here: an IP address and an
889
ASCII string both look like data expressions, but
890
for A records, we want an ASCII string, not a
891
binary IP address. Do I need to turn binary IP
892
addresses into a separate type? */
894
(r2 || expr -> op != expr_ns_add) && *result);
900
case expr_ns_not_exists:
904
log_error ("%s: dns values for functions not supported.",
905
expr -> data.funcall.name);
908
case expr_variable_reference:
909
log_error ("%s: dns values for variables not supported.",
910
expr -> data.variable);
916
case expr_regex_match:
917
case expr_iregex_match:
925
case expr_variable_exists:
926
log_error ("Boolean opcode in evaluate_dns_expression: %d",
937
case expr_const_data:
940
case expr_encapsulate:
941
case expr_host_lookup:
942
case expr_encode_int8:
943
case expr_encode_int16:
944
case expr_encode_int32:
945
case expr_binary_to_ascii:
949
case expr_pick_first_value:
950
case expr_host_decl_name:
951
case expr_config_option:
952
case expr_leased_address:
954
log_error ("Data opcode in evaluate_dns_expression: %d",
958
case expr_extract_int8:
959
case expr_extract_int16:
960
case expr_extract_int32:
962
case expr_lease_time:
963
case expr_dns_transaction:
969
case expr_binary_and:
971
case expr_binary_xor:
972
case expr_client_state:
973
log_error ("Numeric opcode in evaluate_dns_expression: %d",
978
log_error ("Function opcode in evaluate_dns_expression: %d",
986
log_error ("Bogus opcode in evaluate_dns_expression: %d",
990
#endif /* defined (NSUPDATE) */
992
int evaluate_boolean_expression (result, packet, lease, client_state,
993
in_options, cfg_options, scope, expr)
995
struct packet *packet;
997
struct client_state *client_state;
998
struct option_state *in_options;
999
struct option_state *cfg_options;
1000
struct binding_scope **scope;
1001
struct expression *expr;
1003
struct data_string left, right;
1006
struct binding *binding;
1007
struct binding_value *bv, *obv;
1009
int regflags = REG_EXTENDED | REG_NOSUB;
1013
switch (expr -> op) {
1015
*result = check_collection (packet, lease,
1016
expr -> data.check);
1017
#if defined (DEBUG_EXPRESSIONS)
1018
log_debug ("bool: check (%s) returns %s",
1019
expr -> data.check -> name,
1020
*result ? "true" : "false");
1025
case expr_not_equal:
1026
bv = obv = (struct binding_value *)0;
1027
sleft = evaluate_expression (&bv, packet, lease, client_state,
1028
in_options, cfg_options, scope,
1029
expr -> data.equal [0], MDL);
1030
sright = evaluate_expression (&obv, packet, lease,
1031
client_state, in_options,
1033
expr -> data.equal [1], MDL);
1034
if (sleft && sright) {
1035
if (bv -> type != obv -> type)
1036
*result = expr -> op == expr_not_equal;
1038
switch (obv -> type) {
1039
case binding_boolean:
1040
if (bv -> value.boolean == obv -> value.boolean)
1041
*result = expr -> op == expr_equal;
1043
*result = expr -> op == expr_not_equal;
1047
if ((bv -> value.data.len ==
1048
obv -> value.data.len) &&
1049
!memcmp (bv -> value.data.data,
1050
obv -> value.data.data,
1051
obv -> value.data.len))
1052
*result = expr -> op == expr_equal;
1054
*result = expr -> op == expr_not_equal;
1057
case binding_numeric:
1058
if (bv -> value.intval == obv -> value.intval)
1059
*result = expr -> op == expr_equal;
1061
*result = expr -> op == expr_not_equal;
1065
#if defined (NSUPDATE)
1066
/* XXX This should be a comparison for equal
1067
XXX values, not for identity. */
1068
if (bv -> value.dns == obv -> value.dns)
1069
*result = expr -> op == expr_equal;
1071
*result = expr -> op == expr_not_equal;
1073
*result = expr -> op == expr_not_equal;
1077
case binding_function:
1078
if (bv -> value.fundef == obv -> value.fundef)
1079
*result = expr -> op == expr_equal;
1081
*result = expr -> op == expr_not_equal;
1084
*result = expr -> op == expr_not_equal;
1088
} else if (!sleft && !sright)
1089
*result = expr -> op == expr_equal;
1091
*result = expr -> op == expr_not_equal;
1093
#if defined (DEBUG_EXPRESSIONS)
1094
log_debug ("bool: %sequal = %s",
1095
expr -> op == expr_not_equal ? "not" : "",
1096
(*result ? "true" : "false"));
1099
binding_value_dereference (&bv, MDL);
1101
binding_value_dereference (&obv, MDL);
1104
case expr_iregex_match:
1106
regflags |= REG_ICASE;
1109
case expr_regex_match:
1111
memset(&left, 0, sizeof left);
1112
bleft = evaluate_data_expression(&left, packet, lease,
1114
in_options, cfg_options,
1116
expr->data.equal[0], MDL);
1117
memset(&right, 0, sizeof right);
1118
bright = evaluate_data_expression(&right, packet, lease,
1120
in_options, cfg_options,
1122
expr->data.equal[1], MDL);
1125
memset(&re, 0, sizeof(re));
1126
if (bleft && bright &&
1127
(regcomp(&re, (char *)right.data, regflags) == 0) &&
1128
(regexec(&re, (char *)left.data, (size_t)0, NULL, 0) == 0))
1131
#if defined (DEBUG_EXPRESSIONS)
1132
log_debug("bool: %s ~= %s yields %s",
1133
bleft ? print_hex_1(left.len, left.data, 20)
1135
bright ? print_hex_2 (right.len, right.data, 20)
1137
*result ? "true" : "false");
1141
data_string_forget(&left, MDL);
1143
data_string_forget(&right, MDL);
1148
* If we have bleft and bright then we have a good
1149
* syntax, otherwise not.
1151
* XXX: we don't warn on invalid regular expression
1152
* syntax, should we?
1154
return bleft && bright;
1156
/* It shouldn't be possible to configure a regex operator
1157
* when there's no support.
1159
log_fatal("Impossible condition at %s:%d.", MDL);
1164
sleft = evaluate_boolean_expression (&bleft, packet, lease,
1166
in_options, cfg_options,
1168
expr -> data.and [0]);
1170
sright = evaluate_boolean_expression
1171
(&bright, packet, lease, client_state,
1172
in_options, cfg_options,
1173
scope, expr -> data.and [1]);
1175
sright = bright = 0;
1177
#if defined (DEBUG_EXPRESSIONS)
1178
log_debug ("bool: and (%s, %s) = %s",
1179
sleft ? (bleft ? "true" : "false") : "NULL",
1180
sright ? (bright ? "true" : "false") : "NULL",
1182
? (bleft && bright ? "true" : "false") : "NULL"));
1184
if (sleft && sright) {
1185
*result = bleft && bright;
1192
sleft = evaluate_boolean_expression (&bleft, packet, lease,
1194
in_options, cfg_options,
1196
expr -> data.or [0]);
1197
if (!sleft || !bleft)
1198
sright = evaluate_boolean_expression
1199
(&bright, packet, lease, client_state,
1200
in_options, cfg_options,
1201
scope, expr -> data.or [1]);
1204
#if defined (DEBUG_EXPRESSIONS)
1205
log_debug ("bool: or (%s, %s) = %s",
1206
sleft ? (bleft ? "true" : "false") : "NULL",
1207
sright ? (bright ? "true" : "false") : "NULL",
1209
? (bleft || bright ? "true" : "false") : "NULL"));
1211
if (sleft || sright) {
1212
*result = bleft || bright;
1218
sleft = evaluate_boolean_expression (&bleft, packet, lease,
1220
in_options, cfg_options,
1223
#if defined (DEBUG_EXPRESSIONS)
1224
log_debug ("bool: not (%s) = %s",
1225
sleft ? (bleft ? "true" : "false") : "NULL",
1227
? (!bleft ? "true" : "false") : "NULL"));
1237
memset (&left, 0, sizeof left);
1239
!get_option (&left, expr -> data.exists -> universe,
1240
packet, lease, client_state,
1241
in_options, cfg_options, in_options,
1242
scope, expr -> data.exists -> code, MDL))
1246
data_string_forget (&left, MDL);
1248
#if defined (DEBUG_EXPRESSIONS)
1249
log_debug ("bool: exists %s.%s = %s",
1250
expr -> data.option -> universe -> name,
1251
expr -> data.option -> name,
1252
*result ? "true" : "false");
1258
#if defined (DEBUG_EXPRESSIONS)
1259
log_debug ("bool: known = NULL");
1263
#if defined (DEBUG_EXPRESSIONS)
1264
log_debug ("bool: known = %s",
1265
packet -> known ? "true" : "false");
1267
*result = packet -> known;
1271
if (!lease || !(lease -> flags & STATIC_LEASE)) {
1272
#if defined (DEBUG_EXPRESSIONS)
1273
log_debug ("bool: static = false (%s %s %s %d)",
1275
(lease && (lease -> flags & STATIC_LEASE)
1277
piaddr (lease -> ip_addr),
1278
lease ? lease -> flags : 0);
1283
#if defined (DEBUG_EXPRESSIONS)
1284
log_debug ("bool: static = true");
1289
case expr_variable_exists:
1290
if (scope && *scope) {
1291
binding = find_binding (*scope, expr -> data.variable);
1294
if (binding -> value)
1302
#if defined (DEBUG_EXPRESSIONS)
1303
log_debug ("boolean: %s? = %s", expr -> data.variable,
1304
*result ? "true" : "false");
1308
case expr_variable_reference:
1309
if (scope && *scope) {
1310
binding = find_binding (*scope, expr -> data.variable);
1312
if (binding && binding -> value) {
1313
if (binding -> value -> type ==
1315
*result = binding -> value -> value.boolean;
1318
log_error ("binding type %d in %s.",
1319
binding -> value -> type,
1320
"evaluate_boolean_expression");
1327
#if defined (DEBUG_EXPRESSIONS)
1328
log_debug ("boolean: %s = %s", expr -> data.variable,
1329
sleft ? (*result ? "true" : "false") : "NULL");
1334
bv = (struct binding_value *)0;
1335
sleft = evaluate_expression (&bv, packet, lease, client_state,
1336
in_options, cfg_options,
1339
if (bv -> type != binding_boolean)
1340
log_error ("%s() returned type %d in %s.",
1341
expr -> data.funcall.name,
1343
"evaluate_boolean_expression");
1345
*result = bv -> value.boolean;
1346
binding_value_dereference (&bv, MDL);
1348
#if defined (DEBUG_EXPRESSIONS)
1349
log_debug ("boolean: %s() = %s", expr -> data.funcall.name,
1350
sleft ? (*result ? "true" : "false") : "NULL");
1356
case expr_substring:
1362
case expr_const_data:
1365
case expr_encapsulate:
1366
case expr_host_lookup:
1367
case expr_encode_int8:
1368
case expr_encode_int16:
1369
case expr_encode_int32:
1370
case expr_binary_to_ascii:
1372
case expr_pick_first_value:
1373
case expr_host_decl_name:
1374
case expr_config_option:
1375
case expr_leased_address:
1379
log_error ("Data opcode in evaluate_boolean_expression: %d",
1383
case expr_extract_int8:
1384
case expr_extract_int16:
1385
case expr_extract_int32:
1386
case expr_const_int:
1387
case expr_lease_time:
1388
case expr_dns_transaction:
1393
case expr_remainder:
1394
case expr_binary_and:
1395
case expr_binary_or:
1396
case expr_binary_xor:
1397
case expr_client_state:
1398
log_error ("Numeric opcode in evaluate_boolean_expression: %d",
1403
case expr_ns_delete:
1404
case expr_ns_exists:
1405
case expr_ns_not_exists:
1406
log_error ("dns opcode in evaluate_boolean_expression: %d",
1411
log_error ("function definition in evaluate_boolean_expr");
1418
log_error ("Bogus opcode in evaluate_boolean_expression: %d",
1423
int evaluate_data_expression (result, packet, lease, client_state,
1424
in_options, cfg_options, scope, expr, file, line)
1425
struct data_string *result;
1426
struct packet *packet;
1427
struct lease *lease;
1428
struct client_state *client_state;
1429
struct option_state *in_options;
1430
struct option_state *cfg_options;
1431
struct binding_scope **scope;
1432
struct expression *expr;
1436
struct data_string data, other;
1437
unsigned long offset, len, i;
1440
struct binding *binding;
1442
struct binding_value *bv;
1444
switch (expr -> op) {
1445
/* Extract N bytes starting at byte M of a data string. */
1446
case expr_substring:
1447
memset (&data, 0, sizeof data);
1448
s0 = evaluate_data_expression (&data, packet, lease,
1450
in_options, cfg_options, scope,
1451
expr -> data.substring.expr,
1454
/* Evaluate the offset and length. */
1455
s1 = evaluate_numeric_expression
1456
(&offset, packet, lease, client_state, in_options,
1457
cfg_options, scope, expr -> data.substring.offset);
1458
s2 = evaluate_numeric_expression (&len, packet, lease,
1460
in_options, cfg_options,
1462
expr -> data.substring.len);
1464
if (s0 && s1 && s2) {
1465
/* If the offset is after end of the string,
1466
return an empty string. Otherwise, do the
1467
adjustments and return what's left. */
1468
if (data.len > offset) {
1469
data_string_copy (result, &data, file, line);
1470
result -> len -= offset;
1471
if (result -> len > len) {
1472
result -> len = len;
1473
result -> terminated = 0;
1475
result -> data += offset;
1481
#if defined (DEBUG_EXPRESSIONS)
1482
log_debug ("data: substring (%s, %s, %s) = %s",
1483
s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1484
s1 ? print_dec_1 (offset) : "NULL",
1485
s2 ? print_dec_2 (len) : "NULL",
1486
(s3 ? print_hex_2 (result -> len, result -> data, 30)
1490
data_string_forget (&data, MDL);
1495
/* Extract the last N bytes of a data string. */
1497
memset (&data, 0, sizeof data);
1498
s0 = evaluate_data_expression (&data, packet, lease,
1500
in_options, cfg_options, scope,
1501
expr -> data.suffix.expr, MDL);
1502
/* Evaluate the length. */
1503
s1 = evaluate_numeric_expression (&len, packet, lease,
1505
in_options, cfg_options,
1507
expr -> data.suffix.len);
1509
data_string_copy (result, &data, file, line);
1511
/* If we are returning the last N bytes of a
1512
string whose length is <= N, just return
1513
the string - otherwise, compute a new
1514
starting address and decrease the
1516
if (data.len > len) {
1517
result -> data += data.len - len;
1518
result -> len = len;
1520
data_string_forget (&data, MDL);
1523
#if defined (DEBUG_EXPRESSIONS)
1524
log_debug ("data: suffix (%s, %s) = %s",
1525
s0 ? print_hex_1 (data.len, data.data, 30) : "NULL",
1526
s1 ? print_dec_1 (len) : "NULL",
1528
? print_hex_2 (result -> len, result -> data, 30)
1533
/* Convert string to lowercase. */
1535
memset(&data, 0, sizeof data);
1536
s0 = evaluate_data_expression(&data, packet, lease,
1538
in_options, cfg_options, scope,
1539
expr->data.lcase, MDL);
1542
result->len = data.len;
1543
if (buffer_allocate(&result->buffer,
1544
result->len + data.terminated,
1546
result->data = &result->buffer->data[0];
1547
memcpy(result->buffer->data, data.data,
1548
data.len + data.terminated);
1549
result->terminated = data.terminated;
1550
s = (unsigned char *)result->data;
1551
for (i = 0; i < result->len; i++, s++)
1555
log_error("data: lcase: no buffer memory.");
1559
#if defined (DEBUG_EXPRESSIONS)
1560
log_debug("data: lcase (%s) = %s",
1561
s0 ? print_hex_1(data.len, data.data, 30) : "NULL",
1562
s1 ? print_hex_2(result->len, result->data, 30)
1566
data_string_forget(&data, MDL);
1569
/* Convert string to uppercase. */
1571
memset(&data, 0, sizeof data);
1572
s0 = evaluate_data_expression(&data, packet, lease,
1574
in_options, cfg_options, scope,
1575
expr->data.lcase, MDL);
1578
result->len = data.len;
1579
if (buffer_allocate(&result->buffer,
1580
result->len + data.terminated,
1582
result->data = &result->buffer->data[0];
1583
memcpy(result->buffer->data, data.data,
1584
data.len + data.terminated);
1585
result->terminated = data.terminated;
1586
s = (unsigned char *)result->data;
1587
for (i = 0; i < result->len; i++, s++)
1591
log_error("data: lcase: no buffer memory.");
1595
#if defined (DEBUG_EXPRESSIONS)
1596
log_debug("data: ucase (%s) = %s",
1597
s0 ? print_hex_1(data.len, data.data, 30) : "NULL",
1598
s1 ? print_hex_2(result->len, result->data, 30)
1602
data_string_forget(&data, MDL);
1605
/* Extract an option. */
1608
s0 = get_option (result,
1609
expr -> data.option -> universe,
1610
packet, lease, client_state,
1611
in_options, cfg_options, in_options,
1612
scope, expr -> data.option -> code,
1617
#if defined (DEBUG_EXPRESSIONS)
1618
log_debug ("data: option %s.%s = %s",
1619
expr -> data.option -> universe -> name,
1620
expr -> data.option -> name,
1621
s0 ? print_hex_1 (result -> len, result -> data, 60)
1626
case expr_config_option:
1628
s0 = get_option (result,
1629
expr -> data.option -> universe,
1630
packet, lease, client_state,
1631
in_options, cfg_options, cfg_options,
1632
scope, expr -> data.option -> code,
1637
#if defined (DEBUG_EXPRESSIONS)
1638
log_debug ("data: config-option %s.%s = %s",
1639
expr -> data.option -> universe -> name,
1640
expr -> data.option -> name,
1641
s0 ? print_hex_1 (result -> len, result -> data, 60)
1646
/* Combine the hardware type and address. */
1648
/* On the client, hardware is our hardware. */
1650
memset (result, 0, sizeof *result);
1652
client_state -> interface -> hw_address.hbuf;
1654
client_state -> interface -> hw_address.hlen;
1655
#if defined (DEBUG_EXPRESSIONS)
1656
log_debug ("data: hardware = %s",
1657
print_hex_1 (result -> len,
1658
result -> data, 60));
1663
/* The server cares about the client's hardware address,
1664
so only in the case where we are examining a packet can
1665
we return anything. */
1666
if (!packet || !packet -> raw) {
1667
log_error ("data: hardware: raw packet not available");
1670
if (packet -> raw -> hlen > sizeof packet -> raw -> chaddr) {
1671
log_error ("data: hardware: invalid hlen (%d)\n",
1672
packet -> raw -> hlen);
1675
result -> len = packet -> raw -> hlen + 1;
1676
if (buffer_allocate (&result -> buffer, result -> len,
1678
result -> data = &result -> buffer -> data [0];
1679
result -> buffer -> data [0] = packet -> raw -> htype;
1680
memcpy (&result -> buffer -> data [1],
1681
packet -> raw -> chaddr,
1682
packet -> raw -> hlen);
1683
result -> terminated = 0;
1685
log_error ("data: hardware: no memory for buffer.");
1688
#if defined (DEBUG_EXPRESSIONS)
1689
log_debug ("data: hardware = %s",
1690
print_hex_1 (result -> len, result -> data, 60));
1694
/* Extract part of the raw packet. */
1696
if (!packet || !packet -> raw) {
1697
log_error ("data: packet: raw packet not available");
1701
s0 = evaluate_numeric_expression (&offset, packet, lease,
1703
in_options, cfg_options,
1705
expr -> data.packet.offset);
1706
s1 = evaluate_numeric_expression (&len,
1707
packet, lease, client_state,
1708
in_options, cfg_options,
1710
expr -> data.packet.len);
1711
if (s0 && s1 && offset < packet -> packet_length) {
1712
if (offset + len > packet -> packet_length)
1714
packet -> packet_length - offset;
1716
result -> len = len;
1717
if (buffer_allocate (&result -> buffer,
1718
result -> len, file, line)) {
1719
result -> data = &result -> buffer -> data [0];
1720
memcpy (result -> buffer -> data,
1721
(((unsigned char *)(packet -> raw))
1722
+ offset), result -> len);
1723
result -> terminated = 0;
1725
log_error ("data: packet: no buffer memory.");
1731
#if defined (DEBUG_EXPRESSIONS)
1732
log_debug ("data: packet (%ld, %ld) = %s",
1734
s2 ? print_hex_1 (result -> len,
1735
result -> data, 60) : NULL);
1739
/* The encapsulation of all defined options in an
1741
case expr_encapsulate:
1743
s0 = option_space_encapsulate
1744
(result, packet, lease, client_state,
1745
in_options, cfg_options, scope,
1746
&expr -> data.encapsulate);
1750
#if defined (DEBUG_EXPRESSIONS)
1751
log_debug ("data: encapsulate (%s) = %s",
1752
expr -> data.encapsulate.data,
1753
s0 ? print_hex_1 (result -> len,
1754
result -> data, 60) : "NULL");
1758
/* Some constant data... */
1759
case expr_const_data:
1760
#if defined (DEBUG_EXPRESSIONS)
1761
log_debug ("data: const = %s",
1762
print_hex_1 (expr -> data.const_data.len,
1763
expr -> data.const_data.data, 60));
1765
data_string_copy (result,
1766
&expr -> data.const_data, file, line);
1769
/* Hostname lookup... */
1770
case expr_host_lookup:
1771
s0 = do_host_lookup (result, expr -> data.host_lookup);
1772
#if defined (DEBUG_EXPRESSIONS)
1773
log_debug ("data: DNS lookup (%s) = %s",
1774
expr -> data.host_lookup -> hostname,
1776
? print_dotted_quads (result -> len, result -> data)
1781
/* Concatenation... */
1783
memset (&data, 0, sizeof data);
1784
s0 = evaluate_data_expression (&data, packet, lease,
1786
in_options, cfg_options, scope,
1787
expr -> data.concat [0], MDL);
1788
memset (&other, 0, sizeof other);
1789
s1 = evaluate_data_expression (&other, packet, lease,
1791
in_options, cfg_options, scope,
1792
expr -> data.concat [1], MDL);
1795
result -> len = data.len + other.len;
1796
if (!buffer_allocate (&result -> buffer,
1797
(result -> len + other.terminated),
1799
log_error ("data: concat: no memory");
1801
data_string_forget (&data, MDL);
1802
data_string_forget (&other, MDL);
1805
result -> data = &result -> buffer -> data [0];
1806
memcpy (result -> buffer -> data, data.data, data.len);
1807
memcpy (&result -> buffer -> data [data.len],
1808
other.data, other.len + other.terminated);
1812
data_string_forget (&data, MDL);
1814
data_string_forget (&other, MDL);
1815
#if defined (DEBUG_EXPRESSIONS)
1816
log_debug ("data: concat (%s, %s) = %s",
1817
s0 ? print_hex_1 (data.len, data.data, 20) : "NULL",
1818
s1 ? print_hex_2 (other.len, other.data, 20) : "NULL",
1820
? print_hex_3 (result -> len, result -> data, 30)
1825
case expr_encode_int8:
1826
s0 = evaluate_numeric_expression (&len, packet, lease,
1828
in_options, cfg_options,
1830
expr -> data.encode_int);
1833
if (!buffer_allocate (&result -> buffer,
1835
log_error ("data: encode_int8: no memory");
1839
result -> data = &result -> buffer -> data [0];
1840
result -> buffer -> data [0] = len;
1845
#if defined (DEBUG_EXPRESSIONS)
1847
log_debug ("data: encode_int8 (NULL) = NULL");
1849
log_debug ("data: encode_int8 (%ld) = %s", len,
1850
print_hex_2 (result -> len,
1851
result -> data, 20));
1856
case expr_encode_int16:
1857
s0 = evaluate_numeric_expression (&len, packet, lease,
1859
in_options, cfg_options,
1861
expr -> data.encode_int);
1864
if (!buffer_allocate (&result -> buffer, 2,
1866
log_error ("data: encode_int16: no memory");
1870
result -> data = &result -> buffer -> data [0];
1871
putUShort (result -> buffer -> data, len);
1876
#if defined (DEBUG_EXPRESSIONS)
1878
log_debug ("data: encode_int16 (NULL) = NULL");
1880
log_debug ("data: encode_int16 (%ld) = %s", len,
1881
print_hex_2 (result -> len,
1882
result -> data, 20));
1886
case expr_encode_int32:
1887
s0 = evaluate_numeric_expression (&len, packet, lease,
1889
in_options, cfg_options,
1891
expr -> data.encode_int);
1894
if (!buffer_allocate (&result -> buffer, 4,
1896
log_error ("data: encode_int32: no memory");
1900
result -> data = &result -> buffer -> data [0];
1901
putULong (result -> buffer -> data, len);
1906
#if defined (DEBUG_EXPRESSIONS)
1908
log_debug ("data: encode_int32 (NULL) = NULL");
1910
log_debug ("data: encode_int32 (%ld) = %s", len,
1911
print_hex_2 (result -> len,
1912
result -> data, 20));
1916
case expr_binary_to_ascii:
1917
/* Evaluate the base (offset) and width (len): */
1918
s0 = evaluate_numeric_expression
1919
(&offset, packet, lease, client_state, in_options,
1920
cfg_options, scope, expr -> data.b2a.base);
1921
s1 = evaluate_numeric_expression (&len, packet, lease,
1923
in_options, cfg_options,
1925
expr -> data.b2a.width);
1927
/* Evaluate the separator string. */
1928
memset (&data, 0, sizeof data);
1929
s2 = evaluate_data_expression (&data, packet, lease,
1931
in_options, cfg_options, scope,
1932
expr -> data.b2a.separator,
1935
/* Evaluate the data to be converted. */
1936
memset (&other, 0, sizeof other);
1937
s3 = evaluate_data_expression (&other, packet, lease,
1939
in_options, cfg_options, scope,
1940
expr -> data.b2a.buffer, MDL);
1942
if (s0 && s1 && s2 && s3) {
1945
if (len != 8 && len != 16 && len != 32) {
1946
log_info ("binary_to_ascii: %s %ld!",
1947
"invalid width", len);
1953
/* The buffer must be a multiple of the number's
1955
if (other.len % len) {
1956
log_info ("binary-to-ascii: %s %d %s %ld!",
1957
"length of buffer", other.len,
1958
"not a multiple of width", len);
1963
/* Count the width of the output. */
1965
for (i = 0; i < other.len; i += len) {
1968
if (other.data [i] < 8)
1970
else if (other.data [i] < 64)
1974
} else if (offset == 10) {
1975
if (other.data [i] < 10)
1977
else if (other.data [i] < 100)
1981
} else if (offset == 16) {
1982
if (other.data [i] < 16)
1987
buflen += (converted_length
1991
buflen += (converted_length
1994
if (i + len != other.len)
1998
if (!buffer_allocate (&result -> buffer,
1999
buflen + 1, file, line)) {
2000
log_error ("data: binary-to-ascii: no memory");
2004
result -> data = &result -> buffer -> data [0];
2005
result -> len = buflen;
2006
result -> terminated = 1;
2009
for (i = 0; i < other.len; i += len) {
2010
buflen += (binary_to_ascii
2011
(&result -> buffer -> data [buflen],
2012
&other.data [i], offset, len));
2013
if (i + len != other.len) {
2015
buffer -> data [buflen],
2016
data.data, data.len);
2020
/* NUL terminate. */
2021
result -> buffer -> data [buflen] = 0;
2027
#if defined (DEBUG_EXPRESSIONS)
2028
log_debug ("data: binary-to-ascii (%s, %s, %s, %s) = %s",
2029
s0 ? print_dec_1 (offset) : "NULL",
2030
s1 ? print_dec_2 (len) : "NULL",
2031
s2 ? print_hex_1 (data.len, data.data, 30) : "NULL",
2032
s3 ? print_hex_2 (other.len, other.data, 30) : "NULL",
2033
(status ? print_hex_3 (result -> len, result -> data, 30)
2037
data_string_forget (&data, MDL);
2039
data_string_forget (&other, MDL);
2045
/* Evaluate the width (len): */
2046
s0 = evaluate_numeric_expression
2047
(&len, packet, lease, client_state, in_options,
2048
cfg_options, scope, expr -> data.reverse.width);
2050
/* Evaluate the data. */
2051
memset (&data, 0, sizeof data);
2052
s1 = evaluate_data_expression (&data, packet, lease,
2054
in_options, cfg_options, scope,
2055
expr -> data.reverse.buffer,
2061
/* The buffer must be a multiple of the number's
2063
if (data.len % len) {
2064
log_info ("reverse: %s %d %s %ld!",
2065
"length of buffer", data.len,
2066
"not a multiple of width", len);
2071
/* XXX reverse in place? I don't think we can. */
2072
if (!buffer_allocate (&result -> buffer,
2073
data.len, file, line)) {
2074
log_error ("data: reverse: no memory");
2078
result -> data = &result -> buffer -> data [0];
2079
result -> len = data.len;
2080
result -> terminated = 0;
2082
for (i = 0; i < data.len; i += len) {
2083
memcpy (&result -> buffer -> data [i],
2084
&data.data [data.len - i - len], len);
2091
#if defined (DEBUG_EXPRESSIONS)
2092
log_debug ("data: reverse (%s, %s) = %s",
2093
s0 ? print_dec_1 (len) : "NULL",
2094
s1 ? print_hex_1 (data.len, data.data, 30) : "NULL",
2095
(status ? print_hex_3 (result -> len, result -> data, 30)
2099
data_string_forget (&data, MDL);
2104
case expr_leased_address:
2106
log_debug("data: \"leased-address\" configuration "
2107
"directive: there is no lease associated "
2108
"with this client.");
2111
result -> len = lease -> ip_addr.len;
2112
if (buffer_allocate (&result -> buffer, result -> len,
2114
result -> data = &result -> buffer -> data [0];
2115
memcpy (&result -> buffer -> data [0],
2116
lease -> ip_addr.iabuf, lease -> ip_addr.len);
2117
result -> terminated = 0;
2119
log_error ("data: leased-address: no memory.");
2122
#if defined (DEBUG_EXPRESSIONS)
2123
log_debug ("data: leased-address = %s",
2124
print_hex_1 (result -> len, result -> data, 60));
2128
case expr_pick_first_value:
2129
memset (&data, 0, sizeof data);
2130
if ((evaluate_data_expression
2132
lease, client_state, in_options, cfg_options,
2133
scope, expr -> data.pick_first_value.car, MDL))) {
2134
#if defined (DEBUG_EXPRESSIONS)
2135
log_debug ("data: pick_first_value (%s, xxx)",
2136
print_hex_1 (result -> len,
2137
result -> data, 40));
2142
if (expr -> data.pick_first_value.cdr &&
2143
(evaluate_data_expression
2145
lease, client_state, in_options, cfg_options,
2146
scope, expr -> data.pick_first_value.cdr, MDL))) {
2147
#if defined (DEBUG_EXPRESSIONS)
2148
log_debug ("data: pick_first_value (NULL, %s)",
2149
print_hex_1 (result -> len,
2150
result -> data, 40));
2155
#if defined (DEBUG_EXPRESSIONS)
2156
log_debug ("data: pick_first_value (NULL, NULL) = NULL");
2160
case expr_host_decl_name:
2161
if (!lease || !lease -> host) {
2162
log_error ("data: host_decl_name: not available");
2165
result -> len = strlen (lease -> host -> name);
2166
if (buffer_allocate (&result -> buffer,
2167
result -> len + 1, file, line)) {
2168
result -> data = &result -> buffer -> data [0];
2169
strcpy ((char *)&result -> buffer -> data [0],
2170
lease -> host -> name);
2171
result -> terminated = 1;
2173
log_error ("data: host-decl-name: no memory.");
2176
#if defined (DEBUG_EXPRESSIONS)
2177
log_debug ("data: host-decl-name = %s", lease -> host -> name);
2182
#if defined (DEBUG_EXPRESSIONS)
2183
log_debug ("data: null = NULL");
2187
case expr_variable_reference:
2188
if (scope && *scope) {
2189
binding = find_binding (*scope, expr -> data.variable);
2191
if (binding && binding -> value) {
2192
if (binding -> value -> type == binding_data) {
2193
data_string_copy (result,
2194
&binding -> value -> value.data,
2197
} else if (binding -> value -> type != binding_data) {
2198
log_error ("binding type %d in %s.",
2199
binding -> value -> type,
2200
"evaluate_data_expression");
2208
#if defined (DEBUG_EXPRESSIONS)
2209
log_debug ("data: %s = %s", expr -> data.variable,
2210
s0 ? print_hex_1 (result -> len,
2211
result -> data, 50) : "NULL");
2216
bv = (struct binding_value *)0;
2217
s0 = evaluate_expression (&bv, packet, lease, client_state,
2218
in_options, cfg_options,
2221
if (bv -> type != binding_data)
2222
log_error ("%s() returned type %d in %s.",
2223
expr -> data.funcall.name,
2225
"evaluate_data_expression");
2227
data_string_copy (result, &bv -> value.data,
2229
binding_value_dereference (&bv, MDL);
2231
#if defined (DEBUG_EXPRESSIONS)
2232
log_debug ("data: %s = %s", expr -> data.funcall.name,
2233
s0 ? print_hex_1 (result -> len,
2234
result -> data, 50) : "NULL");
2238
/* Extract the filename. */
2240
if (packet && packet -> raw -> file [0]) {
2242
memchr (packet -> raw -> file, 0,
2243
sizeof packet -> raw -> file);
2245
fn = ((char *)packet -> raw -> file +
2246
sizeof packet -> raw -> file);
2247
result -> len = fn - &(packet -> raw -> file [0]);
2248
if (buffer_allocate (&result -> buffer,
2249
result -> len + 1, file, line)) {
2250
result -> data = &result -> buffer -> data [0];
2251
memcpy (&result -> buffer -> data [0],
2252
packet -> raw -> file,
2254
result -> buffer -> data [result -> len] = 0;
2255
result -> terminated = 1;
2258
log_error ("data: filename: no memory.");
2264
#if defined (DEBUG_EXPRESSIONS)
2265
log_info ("data: filename = \"%s\"",
2266
s0 ? (const char *)(result -> data) : "NULL");
2270
/* Extract the server name. */
2272
if (packet && packet -> raw -> sname [0]) {
2274
memchr (packet -> raw -> sname, 0,
2275
sizeof packet -> raw -> sname);
2277
fn = ((char *)packet -> raw -> sname +
2278
sizeof packet -> raw -> sname);
2279
result -> len = fn - &packet -> raw -> sname [0];
2280
if (buffer_allocate (&result -> buffer,
2281
result -> len + 1, file, line)) {
2282
result -> data = &result -> buffer -> data [0];
2283
memcpy (&result -> buffer -> data [0],
2284
packet -> raw -> sname,
2286
result -> buffer -> data [result -> len] = 0;
2287
result -> terminated = 1;
2290
log_error ("data: sname: no memory.");
2296
#if defined (DEBUG_EXPRESSIONS)
2297
log_info ("data: sname = \"%s\"",
2298
s0 ? (const char *)(result -> data) : "NULL");
2304
case expr_not_equal:
2305
case expr_regex_match:
2306
case expr_iregex_match:
2315
case expr_variable_exists:
2316
log_error ("Boolean opcode in evaluate_data_expression: %d",
2320
case expr_extract_int8:
2321
case expr_extract_int16:
2322
case expr_extract_int32:
2323
case expr_const_int:
2324
case expr_lease_time:
2325
case expr_dns_transaction:
2330
case expr_remainder:
2331
case expr_binary_and:
2332
case expr_binary_or:
2333
case expr_binary_xor:
2334
case expr_client_state:
2335
log_error ("Numeric opcode in evaluate_data_expression: %d",
2340
case expr_ns_delete:
2341
case expr_ns_exists:
2342
case expr_ns_not_exists:
2343
log_error ("dns update opcode in evaluate_data_expression: %d",
2348
log_error ("function definition in evaluate_data_expression");
2355
log_error ("Bogus opcode in evaluate_data_expression: %d", expr -> op);
2359
int evaluate_numeric_expression (result, packet, lease, client_state,
2360
in_options, cfg_options, scope, expr)
2361
unsigned long *result;
2362
struct packet *packet;
2363
struct lease *lease;
2364
struct client_state *client_state;
2365
struct option_state *in_options;
2366
struct option_state *cfg_options;
2367
struct binding_scope **scope;
2368
struct expression *expr;
2370
struct data_string data;
2371
int status, sleft, sright;
2372
#if defined (NSUPDATE)
2376
struct expression *cur, *next;
2377
struct binding *binding;
2378
struct binding_value *bv;
2379
unsigned long ileft, iright;
2381
switch (expr -> op) {
2384
case expr_not_equal:
2385
case expr_regex_match:
2386
case expr_iregex_match:
2395
case expr_variable_exists:
2396
log_error ("Boolean opcode in evaluate_numeric_expression: %d",
2400
case expr_substring:
2406
case expr_const_data:
2409
case expr_encapsulate:
2410
case expr_host_lookup:
2411
case expr_encode_int8:
2412
case expr_encode_int16:
2413
case expr_encode_int32:
2414
case expr_binary_to_ascii:
2418
case expr_pick_first_value:
2419
case expr_host_decl_name:
2420
case expr_config_option:
2421
case expr_leased_address:
2423
log_error ("Data opcode in evaluate_numeric_expression: %d",
2427
case expr_extract_int8:
2428
memset (&data, 0, sizeof data);
2429
status = evaluate_data_expression
2430
(&data, packet, lease, client_state, in_options,
2431
cfg_options, scope, expr -> data.extract_int, MDL);
2433
*result = data.data [0];
2434
#if defined (DEBUG_EXPRESSIONS)
2435
log_debug ("num: extract_int8 (%s) = %s",
2436
status ? print_hex_1 (data.len, data.data, 60) : "NULL",
2437
status ? print_dec_1 (*result) : "NULL" );
2439
if (status) data_string_forget (&data, MDL);
2442
case expr_extract_int16:
2443
memset (&data, 0, sizeof data);
2444
status = (evaluate_data_expression
2445
(&data, packet, lease, client_state, in_options,
2446
cfg_options, scope, expr -> data.extract_int, MDL));
2447
if (status && data.len >= 2)
2448
*result = getUShort (data.data);
2449
#if defined (DEBUG_EXPRESSIONS)
2450
log_debug ("num: extract_int16 (%s) = %ld",
2451
((status && data.len >= 2) ?
2452
print_hex_1 (data.len, data.data, 60) : "NULL"),
2455
if (status) data_string_forget (&data, MDL);
2456
return (status && data.len >= 2);
2458
case expr_extract_int32:
2459
memset (&data, 0, sizeof data);
2460
status = (evaluate_data_expression
2461
(&data, packet, lease, client_state, in_options,
2462
cfg_options, scope, expr -> data.extract_int, MDL));
2463
if (status && data.len >= 4)
2464
*result = getULong (data.data);
2465
#if defined (DEBUG_EXPRESSIONS)
2466
log_debug ("num: extract_int32 (%s) = %ld",
2467
((status && data.len >= 4) ?
2468
print_hex_1 (data.len, data.data, 60) : "NULL"),
2471
if (status) data_string_forget (&data, MDL);
2472
return (status && data.len >= 4);
2474
case expr_const_int:
2475
*result = expr -> data.const_int;
2476
#if defined (DEBUG_EXPRESSIONS)
2477
log_debug ("number: CONSTANT = %ld", *result);
2481
case expr_lease_time:
2483
log_error ("data: leased_lease: not available");
2486
if (lease -> ends < cur_time) {
2487
log_error ("%s %lu when it is now %lu",
2488
"data: lease_time: lease ends at",
2489
(long)(lease -> ends), (long)cur_time);
2492
*result = lease -> ends - cur_time;
2493
#if defined (DEBUG_EXPRESSIONS)
2494
log_debug ("number: lease-time = (%lu - %lu) = %ld",
2500
case expr_dns_transaction:
2501
#if !defined (NSUPDATE)
2504
if (!resolver_inited) {
2505
minires_ninit (&resolver_state);
2506
resolver_inited = 1;
2507
resolver_state.retrans = 1;
2508
resolver_state.retry = 1;
2513
next = cur -> data.dns_transaction.cdr;
2515
status = (evaluate_dns_expression
2517
lease, client_state, in_options, cfg_options,
2518
scope, cur -> data.dns_transaction.car));
2521
ISC_LIST_APPEND (uq, nut, r_link);
2525
/* Do the update and record the error code, if there was
2526
an error; otherwise set it to NOERROR. */
2527
*result = minires_nupdate (&resolver_state,
2528
ISC_LIST_HEAD (uq));
2531
print_dns_status ((int)*result, &uq);
2534
while (!ISC_LIST_EMPTY (uq)) {
2535
ns_updrec *tmp = ISC_LIST_HEAD (uq);
2536
ISC_LIST_UNLINK (uq, tmp, r_link);
2537
if (tmp -> r_data_ephem) {
2538
dfree (tmp -> r_data_ephem, MDL);
2539
tmp -> r_data = (unsigned char *)0;
2540
tmp -> r_data_ephem = (unsigned char *)0;
2542
minires_freeupdrec (tmp);
2545
#endif /* NSUPDATE */
2547
case expr_variable_reference:
2548
if (scope && *scope) {
2549
binding = find_binding (*scope, expr -> data.variable);
2551
if (binding && binding -> value) {
2552
if (binding -> value -> type == binding_numeric) {
2553
*result = binding -> value -> value.intval;
2556
log_error ("binding type %d in %s.",
2557
binding -> value -> type,
2558
"evaluate_numeric_expression");
2565
#if defined (DEBUG_EXPRESSIONS)
2567
log_debug ("numeric: %s = %ld",
2568
expr -> data.variable, *result);
2570
log_debug ("numeric: %s = NULL",
2571
expr -> data.variable);
2576
bv = (struct binding_value *)0;
2577
status = evaluate_expression (&bv, packet, lease,
2579
in_options, cfg_options,
2582
if (bv -> type != binding_numeric)
2583
log_error ("%s() returned type %d in %s.",
2584
expr -> data.funcall.name,
2586
"evaluate_numeric_expression");
2588
*result = bv -> value.intval;
2589
binding_value_dereference (&bv, MDL);
2591
#if defined (DEBUG_EXPRESSIONS)
2592
log_debug ("data: %s = %ld", expr -> data.funcall.name,
2593
status ? *result : 0);
2598
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2600
in_options, cfg_options,
2602
expr -> data.and [0]);
2603
sright = evaluate_numeric_expression (&iright, packet, lease,
2605
in_options, cfg_options,
2607
expr -> data.and [1]);
2609
#if defined (DEBUG_EXPRESSIONS)
2610
if (sleft && sright)
2611
log_debug ("num: %ld + %ld = %ld",
2612
ileft, iright, ileft + iright);
2614
log_debug ("num: %ld + NULL = NULL", ileft);
2616
log_debug ("num: NULL + %ld = NULL", iright);
2618
if (sleft && sright) {
2619
*result = ileft + iright;
2625
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2627
in_options, cfg_options,
2629
expr -> data.and [0]);
2630
sright = evaluate_numeric_expression (&iright, packet, lease,
2632
in_options, cfg_options,
2634
expr -> data.and [1]);
2636
#if defined (DEBUG_EXPRESSIONS)
2637
if (sleft && sright)
2638
log_debug ("num: %ld - %ld = %ld",
2639
ileft, iright, ileft - iright);
2641
log_debug ("num: %ld - NULL = NULL", ileft);
2643
log_debug ("num: NULL - %ld = NULL", iright);
2645
if (sleft && sright) {
2646
*result = ileft - iright;
2652
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2654
in_options, cfg_options,
2656
expr -> data.and [0]);
2657
sright = evaluate_numeric_expression (&iright, packet, lease,
2659
in_options, cfg_options,
2661
expr -> data.and [1]);
2663
#if defined (DEBUG_EXPRESSIONS)
2664
if (sleft && sright)
2665
log_debug ("num: %ld * %ld = %ld",
2666
ileft, iright, ileft * iright);
2668
log_debug ("num: %ld * NULL = NULL", ileft);
2670
log_debug ("num: NULL * %ld = NULL", iright);
2672
if (sleft && sright) {
2673
*result = ileft * iright;
2679
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2681
in_options, cfg_options,
2683
expr -> data.and [0]);
2684
sright = evaluate_numeric_expression (&iright, packet, lease,
2686
in_options, cfg_options,
2688
expr -> data.and [1]);
2690
#if defined (DEBUG_EXPRESSIONS)
2691
if (sleft && sright) {
2693
log_debug ("num: %ld / %ld = %ld",
2694
ileft, iright, ileft / iright);
2696
log_debug ("num: %ld / %ld = NULL",
2699
log_debug ("num: %ld / NULL = NULL", ileft);
2701
log_debug ("num: NULL / %ld = NULL", iright);
2703
if (sleft && sright && iright) {
2704
*result = ileft / iright;
2709
case expr_remainder:
2710
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2712
in_options, cfg_options,
2714
expr -> data.and [0]);
2715
sright = evaluate_numeric_expression (&iright, packet, lease,
2717
in_options, cfg_options,
2719
expr -> data.and [1]);
2721
#if defined (DEBUG_EXPRESSIONS)
2722
if (sleft && sright) {
2724
log_debug ("num: %ld %% %ld = %ld",
2725
ileft, iright, ileft % iright);
2727
log_debug ("num: %ld %% %ld = NULL",
2730
log_debug ("num: %ld %% NULL = NULL", ileft);
2732
log_debug ("num: NULL %% %ld = NULL", iright);
2734
if (sleft && sright && iright) {
2735
*result = ileft % iright;
2740
case expr_binary_and:
2741
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2743
in_options, cfg_options,
2745
expr -> data.and [0]);
2746
sright = evaluate_numeric_expression (&iright, packet, lease,
2748
in_options, cfg_options,
2750
expr -> data.and [1]);
2752
#if defined (DEBUG_EXPRESSIONS)
2753
if (sleft && sright)
2754
log_debug ("num: %ld | %ld = %ld",
2755
ileft, iright, ileft & iright);
2757
log_debug ("num: %ld & NULL = NULL", ileft);
2759
log_debug ("num: NULL & %ld = NULL", iright);
2761
if (sleft && sright) {
2762
*result = ileft & iright;
2767
case expr_binary_or:
2768
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2770
in_options, cfg_options,
2772
expr -> data.and [0]);
2773
sright = evaluate_numeric_expression (&iright, packet, lease,
2775
in_options, cfg_options,
2777
expr -> data.and [1]);
2779
#if defined (DEBUG_EXPRESSIONS)
2780
if (sleft && sright)
2781
log_debug ("num: %ld | %ld = %ld",
2782
ileft, iright, ileft | iright);
2784
log_debug ("num: %ld | NULL = NULL", ileft);
2786
log_debug ("num: NULL | %ld = NULL", iright);
2788
if (sleft && sright) {
2789
*result = ileft | iright;
2794
case expr_binary_xor:
2795
sleft = evaluate_numeric_expression (&ileft, packet, lease,
2797
in_options, cfg_options,
2799
expr -> data.and [0]);
2800
sright = evaluate_numeric_expression (&iright, packet, lease,
2802
in_options, cfg_options,
2804
expr -> data.and [1]);
2806
#if defined (DEBUG_EXPRESSIONS)
2807
if (sleft && sright)
2808
log_debug ("num: %ld ^ %ld = %ld",
2809
ileft, iright, ileft ^ iright);
2811
log_debug ("num: %ld ^ NULL = NULL", ileft);
2813
log_debug ("num: NULL ^ %ld = NULL", iright);
2815
if (sleft && sright) {
2816
*result = ileft ^ iright;
2821
case expr_client_state:
2823
#if defined (DEBUG_EXPRESSIONS)
2824
log_debug ("num: client-state = %d",
2825
client_state -> state);
2827
*result = client_state -> state;
2830
#if defined (DEBUG_EXPRESSIONS)
2831
log_debug ("num: client-state = NULL");
2837
case expr_ns_delete:
2838
case expr_ns_exists:
2839
case expr_ns_not_exists:
2840
log_error ("dns opcode in evaluate_numeric_expression: %d",
2845
log_error ("function definition in evaluate_numeric_expr");
2852
log_fatal("Impossible case at %s:%d. Undefined operator "
2853
"%d.", MDL, expr->op);
2857
log_error ("evaluate_numeric_expression: bogus opcode %d", expr -> op);
2861
/* Return data hanging off of an option cache structure, or if there
2862
isn't any, evaluate the expression hanging off of it and return the
2863
result of that evaluation. There should never be both an expression
2864
and a valid data_string. */
2866
int evaluate_option_cache (result, packet, lease, client_state,
2867
in_options, cfg_options, scope, oc, file, line)
2868
struct data_string *result;
2869
struct packet *packet;
2870
struct lease *lease;
2871
struct client_state *client_state;
2872
struct option_state *in_options;
2873
struct option_state *cfg_options;
2874
struct binding_scope **scope;
2875
struct option_cache *oc;
2879
if (oc->data.data != NULL) {
2880
data_string_copy (result, &oc -> data, file, line);
2883
if (!oc -> expression)
2885
return evaluate_data_expression (result, packet, lease, client_state,
2886
in_options, cfg_options, scope,
2887
oc -> expression, file, line);
2890
/* Evaluate an option cache and extract a boolean from the result,
2891
returning the boolean. Return false if there is no data. */
2893
int evaluate_boolean_option_cache (ignorep, packet,
2894
lease, client_state, in_options,
2895
cfg_options, scope, oc, file, line)
2897
struct packet *packet;
2898
struct lease *lease;
2899
struct client_state *client_state;
2900
struct option_state *in_options;
2901
struct option_state *cfg_options;
2902
struct binding_scope **scope;
2903
struct option_cache *oc;
2907
struct data_string ds;
2910
/* So that we can be called with option_lookup as an argument. */
2911
if (!oc || !in_options)
2914
memset (&ds, 0, sizeof ds);
2915
if (!evaluate_option_cache (&ds, packet,
2916
lease, client_state, in_options,
2917
cfg_options, scope, oc, file, line))
2920
/* The boolean option cache is actually a trinary value. Zero is
2921
* off, one is on, and 2 is 'ignore'.
2924
result = ds.data [0];
2927
if (ignorep != NULL)
2929
} else if (ignorep != NULL)
2933
data_string_forget (&ds, MDL);
2938
/* Evaluate a boolean expression and return the result of the evaluation,
2939
or FALSE if it failed. */
2941
int evaluate_boolean_expression_result (ignorep, packet, lease, client_state,
2942
in_options, cfg_options, scope, expr)
2944
struct packet *packet;
2945
struct lease *lease;
2946
struct client_state *client_state;
2947
struct option_state *in_options;
2948
struct option_state *cfg_options;
2949
struct binding_scope **scope;
2950
struct expression *expr;
2954
/* So that we can be called with option_lookup as an argument. */
2958
if (!evaluate_boolean_expression (&result, packet, lease, client_state,
2959
in_options, cfg_options,
2972
/* Dereference an expression node, and if the reference count goes to zero,
2973
dereference any data it refers to, and then free it. */
2974
void expression_dereference (eptr, file, line)
2975
struct expression **eptr;
2979
struct expression *expr = *eptr;
2981
/* Zero the pointer. */
2982
*eptr = (struct expression *)0;
2984
/* Decrement the reference count. If it's nonzero, we're
2987
rc_register (file, line, eptr, expr, expr -> refcnt, 1, RC_MISC);
2988
if (expr -> refcnt > 0)
2990
if (expr -> refcnt < 0) {
2991
log_error ("%s(%d): negative refcnt!", file, line);
2992
#if defined (DEBUG_RC_HISTORY)
2993
dump_rc_history (expr);
2995
#if defined (POINTER_DEBUG)
3002
/* Dereference subexpressions. */
3003
switch (expr -> op) {
3004
/* All the binary operators can be handled the same way. */
3006
case expr_not_equal:
3007
case expr_regex_match:
3008
case expr_iregex_match:
3016
case expr_remainder:
3017
case expr_binary_and:
3018
case expr_binary_or:
3019
case expr_binary_xor:
3020
case expr_client_state:
3021
if (expr -> data.equal [0])
3022
expression_dereference (&expr -> data.equal [0],
3024
if (expr -> data.equal [1])
3025
expression_dereference (&expr -> data.equal [1],
3029
case expr_substring:
3030
if (expr -> data.substring.expr)
3031
expression_dereference (&expr -> data.substring.expr,
3033
if (expr -> data.substring.offset)
3034
expression_dereference (&expr -> data.substring.offset,
3036
if (expr -> data.substring.len)
3037
expression_dereference (&expr -> data.substring.len,
3042
if (expr -> data.suffix.expr)
3043
expression_dereference (&expr -> data.suffix.expr,
3045
if (expr -> data.suffix.len)
3046
expression_dereference (&expr -> data.suffix.len,
3051
if (expr->data.lcase)
3052
expression_dereference(&expr->data.lcase, MDL);
3056
if (expr->data.ucase)
3057
expression_dereference(&expr->data.ucase, MDL);
3061
if (expr -> data.not)
3062
expression_dereference (&expr -> data.not, file, line);
3066
if (expr -> data.packet.offset)
3067
expression_dereference (&expr -> data.packet.offset,
3069
if (expr -> data.packet.len)
3070
expression_dereference (&expr -> data.packet.len,
3074
case expr_extract_int8:
3075
case expr_extract_int16:
3076
case expr_extract_int32:
3077
if (expr -> data.extract_int)
3078
expression_dereference (&expr -> data.extract_int,
3082
case expr_encode_int8:
3083
case expr_encode_int16:
3084
case expr_encode_int32:
3085
if (expr -> data.encode_int)
3086
expression_dereference (&expr -> data.encode_int,
3090
case expr_encapsulate:
3091
case expr_const_data:
3092
data_string_forget (&expr -> data.const_data, file, line);
3095
case expr_host_lookup:
3096
if (expr -> data.host_lookup)
3097
dns_host_entry_dereference (&expr -> data.host_lookup,
3101
case expr_binary_to_ascii:
3102
if (expr -> data.b2a.base)
3103
expression_dereference (&expr -> data.b2a.base,
3105
if (expr -> data.b2a.width)
3106
expression_dereference (&expr -> data.b2a.width,
3108
if (expr -> data.b2a.separator)
3109
expression_dereference (&expr -> data.b2a.separator,
3111
if (expr -> data.b2a.buffer)
3112
expression_dereference (&expr -> data.b2a.buffer,
3116
case expr_pick_first_value:
3117
if (expr -> data.pick_first_value.car)
3118
expression_dereference (&expr -> data.pick_first_value.car,
3120
if (expr -> data.pick_first_value.cdr)
3121
expression_dereference (&expr -> data.pick_first_value.cdr,
3126
if (expr -> data.reverse.width)
3127
expression_dereference (&expr -> data.reverse.width,
3129
if (expr -> data.reverse.buffer)
3130
expression_dereference
3131
(&expr -> data.reverse.buffer, file, line);
3134
case expr_dns_transaction:
3135
if (expr -> data.dns_transaction.car)
3136
expression_dereference (&expr -> data.dns_transaction.car,
3138
if (expr -> data.dns_transaction.cdr)
3139
expression_dereference (&expr -> data.dns_transaction.cdr,
3144
if (expr -> data.ns_add.rrname)
3145
expression_dereference (&expr -> data.ns_add.rrname,
3147
if (expr -> data.ns_add.rrdata)
3148
expression_dereference (&expr -> data.ns_add.rrdata,
3150
if (expr -> data.ns_add.ttl)
3151
expression_dereference (&expr -> data.ns_add.ttl,
3155
case expr_ns_delete:
3156
case expr_ns_exists:
3157
case expr_ns_not_exists:
3158
if (expr -> data.ns_delete.rrname)
3159
expression_dereference (&expr -> data.ns_delete.rrname,
3161
if (expr -> data.ns_delete.rrdata)
3162
expression_dereference (&expr -> data.ns_delete.rrdata,
3166
case expr_variable_reference:
3167
case expr_variable_exists:
3168
if (expr -> data.variable)
3169
dfree (expr -> data.variable, file, line);
3173
if (expr -> data.funcall.name)
3174
dfree (expr -> data.funcall.name, file, line);
3175
if (expr -> data.funcall.arglist)
3176
expression_dereference (&expr -> data.funcall.arglist,
3181
if (expr -> data.arg.val)
3182
expression_dereference (&expr -> data.arg.val,
3184
if (expr -> data.arg.next)
3185
expression_dereference (&expr -> data.arg.next,
3190
fundef_dereference (&expr -> data.func, file, line);
3193
/* No subexpressions. */
3194
case expr_leased_address:
3195
case expr_lease_time:
3198
case expr_const_int:
3210
free_expression (expr, MDL);
3213
int is_dns_expression (expr)
3214
struct expression *expr;
3216
return (expr -> op == expr_ns_add ||
3217
expr -> op == expr_ns_delete ||
3218
expr -> op == expr_ns_exists ||
3219
expr -> op == expr_ns_not_exists);
3222
int is_boolean_expression (expr)
3223
struct expression *expr;
3225
return (expr -> op == expr_check ||
3226
expr -> op == expr_exists ||
3227
expr -> op == expr_variable_exists ||
3228
expr -> op == expr_equal ||
3229
expr -> op == expr_not_equal ||
3230
expr->op == expr_regex_match ||
3231
expr->op == expr_iregex_match ||
3232
expr -> op == expr_and ||
3233
expr -> op == expr_or ||
3234
expr -> op == expr_not ||
3235
expr -> op == expr_known ||
3236
expr -> op == expr_static);
3239
int is_data_expression (expr)
3240
struct expression *expr;
3242
return (expr->op == expr_substring ||
3243
expr->op == expr_suffix ||
3244
expr->op == expr_lcase ||
3245
expr->op == expr_ucase ||
3246
expr->op == expr_option ||
3247
expr->op == expr_hardware ||
3248
expr->op == expr_const_data ||
3249
expr->op == expr_packet ||
3250
expr->op == expr_concat ||
3251
expr->op == expr_encapsulate ||
3252
expr->op == expr_encode_int8 ||
3253
expr->op == expr_encode_int16 ||
3254
expr->op == expr_encode_int32 ||
3255
expr->op == expr_host_lookup ||
3256
expr->op == expr_binary_to_ascii ||
3257
expr->op == expr_filename ||
3258
expr->op == expr_sname ||
3259
expr->op == expr_reverse ||
3260
expr->op == expr_pick_first_value ||
3261
expr->op == expr_host_decl_name ||
3262
expr->op == expr_leased_address ||
3263
expr->op == expr_config_option ||
3264
expr->op == expr_null);
3267
int is_numeric_expression (expr)
3268
struct expression *expr;
3270
return (expr -> op == expr_extract_int8 ||
3271
expr -> op == expr_extract_int16 ||
3272
expr -> op == expr_extract_int32 ||
3273
expr -> op == expr_const_int ||
3274
expr -> op == expr_lease_time ||
3275
expr -> op == expr_dns_transaction ||
3276
expr -> op == expr_add ||
3277
expr -> op == expr_subtract ||
3278
expr -> op == expr_multiply ||
3279
expr -> op == expr_divide ||
3280
expr -> op == expr_remainder ||
3281
expr -> op == expr_binary_and ||
3282
expr -> op == expr_binary_or ||
3283
expr -> op == expr_binary_xor ||
3284
expr -> op == expr_client_state);
3287
int is_compound_expression (expr)
3288
struct expression *expr;
3290
return (expr -> op == expr_ns_add ||
3291
expr -> op == expr_ns_delete ||
3292
expr -> op == expr_ns_exists ||
3293
expr -> op == expr_ns_not_exists ||
3294
expr -> op == expr_substring ||
3295
expr -> op == expr_suffix ||
3296
expr -> op == expr_option ||
3297
expr -> op == expr_concat ||
3298
expr -> op == expr_encode_int8 ||
3299
expr -> op == expr_encode_int16 ||
3300
expr -> op == expr_encode_int32 ||
3301
expr -> op == expr_binary_to_ascii ||
3302
expr -> op == expr_reverse ||
3303
expr -> op == expr_pick_first_value ||
3304
expr -> op == expr_config_option ||
3305
expr -> op == expr_extract_int8 ||
3306
expr -> op == expr_extract_int16 ||
3307
expr -> op == expr_extract_int32 ||
3308
expr -> op == expr_dns_transaction);
3311
static int op_val PROTO ((enum expr_op));
3313
static int op_val (op)
3321
case expr_substring:
3326
case expr_encapsulate:
3327
case expr_host_lookup:
3332
case expr_const_data:
3333
case expr_extract_int8:
3334
case expr_extract_int16:
3335
case expr_extract_int32:
3336
case expr_encode_int8:
3337
case expr_encode_int16:
3338
case expr_encode_int32:
3339
case expr_const_int:
3341
case expr_variable_exists:
3343
case expr_binary_to_ascii:
3347
case expr_pick_first_value:
3348
case expr_host_decl_name:
3349
case expr_config_option:
3350
case expr_leased_address:
3351
case expr_lease_time:
3352
case expr_dns_transaction:
3354
case expr_variable_reference:
3356
case expr_ns_delete:
3357
case expr_ns_exists:
3358
case expr_ns_not_exists:
3362
/* XXXDPN: Need to assign sane precedences to these. */
3363
case expr_binary_and:
3364
case expr_binary_or:
3365
case expr_binary_xor:
3366
case expr_client_state:
3370
case expr_not_equal:
3371
case expr_regex_match:
3372
case expr_iregex_match:
3385
case expr_remainder:
3391
int op_precedence (op1, op2)
3392
enum expr_op op1, op2;
3394
return op_val (op1) - op_val (op2);
3397
enum expression_context expression_context (struct expression *expr)
3399
if (is_data_expression (expr))
3400
return context_data;
3401
if (is_numeric_expression (expr))
3402
return context_numeric;
3403
if (is_boolean_expression (expr))
3404
return context_boolean;
3405
if (is_dns_expression (expr))
3410
enum expression_context op_context (op)
3414
/* XXX Why aren't these specific? */
3419
case expr_substring:
3424
case expr_encapsulate:
3425
case expr_host_lookup:
3430
case expr_const_data:
3431
case expr_extract_int8:
3432
case expr_extract_int16:
3433
case expr_extract_int32:
3434
case expr_encode_int8:
3435
case expr_encode_int16:
3436
case expr_encode_int32:
3437
case expr_const_int:
3439
case expr_variable_exists:
3441
case expr_binary_to_ascii:
3445
case expr_pick_first_value:
3446
case expr_host_decl_name:
3447
case expr_config_option:
3448
case expr_leased_address:
3449
case expr_lease_time:
3451
case expr_variable_reference:
3453
case expr_ns_delete:
3454
case expr_ns_exists:
3455
case expr_ns_not_exists:
3456
case expr_dns_transaction:
3463
case expr_not_equal:
3464
case expr_regex_match:
3465
case expr_iregex_match:
3466
return context_data;
3469
return context_boolean;
3472
return context_boolean;
3478
case expr_remainder:
3479
case expr_binary_and:
3480
case expr_binary_or:
3481
case expr_binary_xor:
3482
case expr_client_state:
3483
return context_numeric;
3488
int write_expression (file, expr, col, indent, firstp)
3490
struct expression *expr;
3495
struct expression *e;
3501
/* If this promises to be a fat expression, start a new line. */
3502
if (!firstp && is_compound_expression (expr)) {
3503
indent_spaces (file, indent);
3507
switch (expr -> op) {
3509
col = token_print_indent (file, col, indent, "", "", "null");
3513
col = token_print_indent (file, col, indent, "", "", "check");
3514
col = token_print_indent_concat (file, col, indent,
3516
expr -> data.check -> name,
3520
case expr_regex_match:
3524
case expr_iregex_match:
3528
case expr_not_equal:
3535
col = write_expression (file, expr -> data.equal [0],
3537
col = token_print_indent (file, col, indent, " ", " ", s);
3538
col = write_expression (file, expr -> data.equal [1],
3539
col, indent + 2, 0);
3542
case expr_substring:
3543
col = token_print_indent (file, col, indent, "", "",
3545
col = token_print_indent (file, col, indent, " ", "", "(");
3547
col = write_expression (file, expr -> data.substring.expr,
3549
col = token_print_indent (file, col, indent, "", " ", ",");
3550
col = write_expression (file, expr -> data.substring.offset,
3552
col = token_print_indent (file, col, scol, "", " ", ",");
3553
col = write_expression (file, expr -> data.substring.len,
3555
col = token_print_indent (file, col, indent, "", "", ")");
3559
col = token_print_indent (file, col, indent, "", "", "suffix");
3560
col = token_print_indent (file, col, indent, " ", "", "(");
3562
col = write_expression (file, expr -> data.suffix.expr,
3564
col = token_print_indent (file, col, scol, "", " ", ",");
3565
col = write_expression (file, expr -> data.suffix.len,
3567
col = token_print_indent (file, col, indent, "", "", ")");
3570
col = token_print_indent(file, col, indent, "", "", "lcase");
3571
col = token_print_indent(file, col, indent, " ", "", "(");
3573
col = write_expression(file, expr->data.lcase, col, scol, 1);
3574
col = token_print_indent(file, col, indent, "", "", ")");
3578
col = token_print_indent(file, col, indent, "", "", "ucase");
3579
col = token_print_indent(file, col, indent, " ", "", "(");
3581
col = write_expression(file, expr->data.ucase, col, scol, 1);
3582
col = token_print_indent(file, col, indent, "", "", ")");
3587
col = token_print_indent (file, col, indent, "", "",
3589
col = token_print_indent (file, col, indent, " ", "", "(");
3593
col = write_expression (file, e -> data.concat [0],
3596
if (!e -> data.concat [1])
3598
col = token_print_indent (file, col, scol, "", " ", ",");
3599
if (e -> data.concat [1] -> op == expr_concat) {
3600
e = e -> data.concat [1];
3603
col = write_expression (file, e -> data.concat [1],
3606
col = token_print_indent (file, col, indent, "", "", ")");
3609
case expr_host_lookup:
3610
col = token_print_indent (file, col, indent, "", "",
3612
col = token_print_indent (file, col, indent, " ", "", "(");
3613
col = token_print_indent_concat
3614
(file, col, indent, "", "",
3615
"\"", expr -> data.host_lookup -> hostname, "\"",
3617
col = token_print_indent (file, col, indent, "", "", ")");
3636
case expr_remainder:
3640
case expr_binary_and:
3644
case expr_binary_or:
3648
case expr_binary_xor:
3661
col = token_print_indent (file, col, indent, "", " ", "not");
3662
col = write_expression (file,
3663
expr -> data.not, col, indent + 2, 1);
3670
col = token_print_indent (file, col, indent, "", "", s);
3672
if (expr -> data.option -> universe != &dhcp_universe) {
3673
col = token_print_indent (file, col, indent,
3675
(expr -> data.option ->
3677
col = token_print_indent (file, col, indent, "", "",
3679
col = token_print_indent (file, col, indent, "", "",
3680
expr -> data.option -> name);
3682
col = token_print_indent (file, col, indent, " ", "",
3683
expr -> data.option -> name);
3688
col = token_print_indent (file, col, indent, "", "",
3693
col = token_print_indent (file, col, indent, "", "",
3695
col = token_print_indent (file, col, indent, " ", "", "(");
3697
col = write_expression (file, expr -> data.packet.offset,
3699
col = token_print_indent (file, col, scol, "", " ", ",");
3700
col = write_expression (file, expr -> data.packet.len,
3702
col = token_print_indent (file, col, indent, "", "", ")");
3705
case expr_const_data:
3706
col = token_indent_data_string (file, col, indent, "", "",
3707
&expr -> data.const_data);
3710
case expr_extract_int8:
3713
col = token_print_indent (file, col, indent, "", "",
3715
col = token_print_indent (file, col, indent, " ", "", "(");
3717
col = write_expression (file, expr -> data.extract_int,
3719
col = token_print_indent (file, col, scol, "", " ", ",");
3720
sprintf (obuf, "%d", width);
3721
col = token_print_indent (file, col, scol, " ", "", obuf);
3722
col = token_print_indent (file, col, indent, "", "", ")");
3725
case expr_extract_int16:
3729
case expr_extract_int32:
3733
case expr_encode_int8:
3736
col = token_print_indent (file, col, indent, "", "",
3738
col = token_print_indent (file, col, indent, " ", "", "(");
3740
col = write_expression (file, expr -> data.extract_int,
3742
col = token_print_indent (file, col, scol, "", " ", ",");
3743
sprintf (obuf, "%d", width);
3744
col = token_print_indent (file, col, scol, " ", "", obuf);
3745
col = token_print_indent (file, col, indent, "", "",
3749
case expr_encode_int16:
3753
case expr_encode_int32:
3757
case expr_const_int:
3758
sprintf (obuf, "%lu", expr -> data.const_int);
3759
col = token_print_indent (file, col, indent, "", "", obuf);
3764
goto print_option_name;
3766
case expr_encapsulate:
3767
col = token_print_indent (file, col, indent, "", "",
3769
col = token_indent_data_string (file, col, indent, " ", "",
3770
&expr -> data.encapsulate);
3774
col = token_print_indent (file, col, indent, "", "", "known");
3778
col = token_print_indent (file, col, indent, "", "",
3780
col = token_print_indent (file, col, indent, " ", "", "(");
3782
col = write_expression (file, expr -> data.reverse.width,
3784
col = token_print_indent (file, col, scol, "", " ", ",");
3785
col = write_expression (file, expr -> data.reverse.buffer,
3787
col = token_print_indent (file, col, indent, "", "",
3791
case expr_leased_address:
3792
col = token_print_indent (file, col, indent, "", "",
3796
case expr_client_state:
3797
col = token_print_indent (file, col, indent, "", "",
3801
case expr_binary_to_ascii:
3802
col = token_print_indent (file, col, indent, "", "",
3804
col = token_print_indent (file, col, indent, " ", "",
3807
col = write_expression (file, expr -> data.b2a.base,
3809
col = token_print_indent (file, col, scol, "", " ",
3811
col = write_expression (file, expr -> data.b2a.width,
3813
col = token_print_indent (file, col, scol, "", " ",
3815
col = write_expression (file, expr -> data.b2a.separator,
3817
col = token_print_indent (file, col, scol, "", " ",
3819
col = write_expression (file, expr -> data.b2a.buffer,
3821
col = token_print_indent (file, col, indent, "", "",
3825
case expr_config_option:
3826
s = "config-option";
3827
goto print_option_name;
3829
case expr_host_decl_name:
3830
col = token_print_indent (file, col, indent, "", "",
3834
case expr_pick_first_value:
3836
col = token_print_indent (file, col, indent, "", "",
3838
col = token_print_indent (file, col, indent, " ", "",
3843
col = write_expression (file,
3844
e -> data.pick_first_value.car,
3847
/* We're being very lisp-like right now - instead of
3848
representing this expression as (first middle . last) we're
3849
representing it as (first middle last), which means that the
3850
tail cdr is always nil. Apologies to non-wisp-lizards - may
3851
this obscure way of describing the problem motivate you to
3852
learn more about the one true computing language. */
3853
if (!e -> data.pick_first_value.cdr)
3855
col = token_print_indent (file, col, scol, "", " ",
3857
if (e -> data.pick_first_value.cdr -> op ==
3858
expr_pick_first_value) {
3859
e = e -> data.pick_first_value.cdr;
3862
col = write_expression (file,
3863
e -> data.pick_first_value.cdr,
3866
col = token_print_indent (file, col, indent, "", "",
3870
case expr_lease_time:
3871
col = token_print_indent (file, col, indent, "", "",
3875
case expr_dns_transaction:
3876
col = token_print_indent (file, col, indent, "", "",
3878
col = token_print_indent (file, col, indent, " ", "",
3882
e && e -> op == expr_dns_transaction;
3883
e = e -> data.dns_transaction.cdr) {
3889
col = write_expression (file,
3890
e -> data.dns_transaction.car,
3892
if (e -> data.dns_transaction.cdr)
3893
col = token_print_indent (file, col, scol,
3897
col = write_expression (file, e, col, scol, 0);
3898
col = token_print_indent (file, col, indent, "", "", ")");
3902
col = token_print_indent (file, col, indent, "", "",
3904
col = token_print_indent (file, col, indent, " ", "",
3907
sprintf (obuf, "%d", expr -> data.ns_add.rrclass);
3908
col = token_print_indent (file, col, scol, "", "", obuf);
3909
col = token_print_indent (file, col, scol, "", " ",
3911
sprintf (obuf, "%d", expr -> data.ns_add.rrtype);
3912
col = token_print_indent (file, col, scol, "", "", obuf);
3913
col = token_print_indent (file, col, scol, "", " ",
3915
col = write_expression (file, expr -> data.ns_add.rrname,
3917
col = token_print_indent (file, col, scol, "", " ",
3919
col = write_expression (file, expr -> data.ns_add.rrdata,
3921
col = token_print_indent (file, col, scol, "", " ",
3923
col = write_expression (file, expr -> data.ns_add.ttl,
3925
col = token_print_indent (file, col, indent, "", "",
3929
case expr_ns_delete:
3930
col = token_print_indent (file, col, indent, "", "",
3932
col = token_print_indent (file, col, indent, " ", "",
3936
sprintf (obuf, "%d", expr -> data.ns_add.rrclass);
3937
col = token_print_indent (file, col, scol, "", "", obuf);
3938
col = token_print_indent (file, col, scol, "", " ",
3940
sprintf (obuf, "%d", expr -> data.ns_add.rrtype);
3941
col = token_print_indent (file, col, scol, "", "", obuf);
3942
col = token_print_indent (file, col, scol, "", " ",
3944
col = write_expression (file, expr -> data.ns_add.rrname,
3946
col = token_print_indent (file, col, scol, "", " ",
3948
col = write_expression (file, expr -> data.ns_add.rrdata,
3950
col = token_print_indent (file, col, indent, "", "",
3954
case expr_ns_exists:
3955
col = token_print_indent (file, col, indent, "", "",
3957
col = token_print_indent (file, col, indent, " ", "",
3959
goto finish_ns_small;
3961
case expr_ns_not_exists:
3962
col = token_print_indent (file, col, indent, "", "",
3964
col = token_print_indent (file, col, indent, " ", "",
3966
goto finish_ns_small;
3969
col = token_print_indent (file, col, indent, "", "",
3974
col = token_print_indent (file, col, indent, "", "", "null");
3977
case expr_variable_reference:
3978
col = token_print_indent (file, indent, indent, "", "",
3979
expr -> data.variable);
3982
case expr_variable_exists:
3983
col = token_print_indent (file, indent, indent, "", "",
3985
col = token_print_indent (file, col, indent, " ", "", "(");
3986
col = token_print_indent (file, col, indent, "", "",
3987
expr -> data.variable);
3988
col = token_print_indent (file, col, indent, "", "", ")");
3992
log_fatal ("invalid expression type in print_expression: %d",
3998
struct binding *find_binding (struct binding_scope *scope, const char *name)
4001
struct binding_scope *s;
4003
for (s = scope; s; s = s -> outer) {
4004
for (bp = s -> bindings; bp; bp = bp -> next) {
4005
if (!strcasecmp (name, bp -> name)) {
4010
return (struct binding *)0;
4013
int free_bindings (struct binding_scope *scope, const char *file, int line)
4015
struct binding *bp, *next;
4017
for (bp = scope -> bindings; bp; bp = next) {
4020
dfree (bp -> name, file, line);
4022
binding_value_dereference (&bp -> value, file, line);
4023
dfree (bp, file, line);
4025
scope -> bindings = (struct binding *)0;
4029
int binding_scope_dereference (ptr, file, line)
4030
struct binding_scope **ptr;
4034
struct binding_scope *binding_scope;
4036
if (!ptr || !*ptr) {
4037
log_error ("%s(%d): null pointer", file, line);
4038
#if defined (POINTER_DEBUG)
4045
binding_scope = *ptr;
4046
*ptr = (struct binding_scope *)0;
4047
--binding_scope -> refcnt;
4048
rc_register (file, line, ptr,
4049
binding_scope, binding_scope -> refcnt, 1, RC_MISC);
4050
if (binding_scope -> refcnt > 0)
4053
if (binding_scope -> refcnt < 0) {
4054
log_error ("%s(%d): negative refcnt!", file, line);
4055
#if defined (DEBUG_RC_HISTORY)
4056
dump_rc_history (binding_scope);
4058
#if defined (POINTER_DEBUG)
4065
free_bindings (binding_scope, file, line);
4066
if (binding_scope -> outer)
4067
binding_scope_dereference (&binding_scope -> outer, MDL);
4068
dfree (binding_scope, file, line);
4072
int fundef_dereference (ptr, file, line)
4073
struct fundef **ptr;
4077
struct fundef *bp = *ptr;
4078
struct string_list *sp, *next;
4081
log_error ("%s(%d): null pointer", file, line);
4082
#if defined (POINTER_DEBUG)
4090
log_error ("%s(%d): null pointer", file, line);
4091
#if defined (POINTER_DEBUG)
4099
rc_register (file, line, ptr, bp, bp -> refcnt, 1, RC_MISC);
4100
if (bp -> refcnt < 0) {
4101
log_error ("%s(%d): negative refcnt!", file, line);
4102
#if defined (DEBUG_RC_HISTORY)
4103
dump_rc_history (bp);
4105
#if defined (POINTER_DEBUG)
4111
if (!bp -> refcnt) {
4112
for (sp = bp -> args; sp; sp = next) {
4114
dfree (sp, file, line);
4116
if (bp -> statements)
4117
executable_statement_dereference (&bp -> statements,
4119
dfree (bp, file, line);
4121
*ptr = (struct fundef *)0;
4125
#if defined (NOTYET) /* Post 3.0 final. */
4126
int data_subexpression_length (int *rv,
4127
struct expression *expr)
4129
int crhs, clhs, llhs, lrhs;
4130
switch (expr -> op) {
4131
case expr_substring:
4132
if (expr -> data.substring.len &&
4133
expr -> data.substring.len -> op == expr_const_int) {
4135
(int)expr -> data.substring.len -> data.const_int);
4142
if (expr -> data.suffix.len &&
4143
expr -> data.suffix.len -> op == expr_const_int) {
4145
(int)expr -> data.suffix.len -> data.const_int);
4151
return data_subexpression_length(rv, expr->data.lcase);
4154
return data_subexpression_length(rv, expr->data.ucase);
4157
clhs = data_subexpression_length (&llhs,
4158
expr -> data.concat [0]);
4159
crhs = data_subexpression_length (&lrhs,
4160
expr -> data.concat [1]);
4161
if (crhs == 0 || clhs == 0)
4170
case expr_const_data:
4171
*rv = expr -> data.const_data.len;
4175
return data_subexpression_length (rv,
4176
expr -> data.reverse.buffer);
4178
case expr_leased_address:
4179
case expr_lease_time:
4183
case expr_pick_first_value:
4184
clhs = data_subexpression_length (&llhs,
4185
expr -> data.concat [0]);
4186
crhs = data_subexpression_length (&lrhs,
4187
expr -> data.concat [1]);
4188
if (crhs == 0 || clhs == 0)
4196
case expr_binary_to_ascii:
4197
case expr_config_option:
4198
case expr_host_decl_name:
4199
case expr_encapsulate:
4202
case expr_host_lookup:
4208
case expr_regex_match:
4209
case expr_iregex_match:
4213
case expr_extract_int8:
4214
case expr_extract_int16:
4215
case expr_extract_int32:
4216
case expr_encode_int8:
4217
case expr_encode_int16:
4218
case expr_encode_int32:
4219
case expr_const_int:
4222
case expr_dns_transaction:
4225
case expr_ns_delete:
4226
case expr_ns_exists:
4227
case expr_ns_not_exists:
4228
case expr_not_equal:
4230
case expr_variable_exists:
4231
case expr_variable_reference:
4239
case expr_remainder:
4240
case expr_binary_and:
4241
case expr_binary_or:
4242
case expr_binary_xor:
4243
case expr_client_state:
4249
int expr_valid_for_context (struct expression *expr,
4250
enum expression_context context)
4252
/* We don't know at parse time what type of value a function may
4253
return, so we can't flag an error on it. */
4254
if (expr -> op == expr_funcall ||
4255
expr -> op == expr_variable_reference)
4262
case context_boolean:
4263
if (is_boolean_expression (expr))
4268
if (is_data_expression (expr))
4272
case context_numeric:
4273
if (is_numeric_expression (expr))
4278
if (is_dns_expression (expr)) {
4283
case context_data_or_numeric:
4284
if (is_numeric_expression (expr) ||
4285
is_data_expression (expr)) {
4290
case context_function:
4291
if (expr -> op == expr_function)
4299
struct binding *create_binding (struct binding_scope **scope, const char *name)
4301
struct binding *binding;
4304
if (!binding_scope_allocate (scope, MDL))
4305
return (struct binding *)0;
4308
binding = find_binding (*scope, name);
4310
binding = dmalloc (sizeof *binding, MDL);
4312
return (struct binding *)0;
4314
memset (binding, 0, sizeof *binding);
4315
binding -> name = dmalloc (strlen (name) + 1, MDL);
4316
if (!binding -> name) {
4317
dfree (binding, MDL);
4318
return (struct binding *)0;
4320
strcpy (binding -> name, name);
4322
binding -> next = (*scope) -> bindings;
4323
(*scope) -> bindings = binding;
4330
int bind_ds_value (struct binding_scope **scope,
4332
struct data_string *value)
4334
struct binding *binding;
4336
binding = create_binding (scope, name);
4340
if (binding -> value)
4341
binding_value_dereference (&binding -> value, MDL);
4343
if (!binding_value_allocate (&binding -> value, MDL))
4346
data_string_copy (&binding -> value -> value.data, value, MDL);
4347
binding -> value -> type = binding_data;
4353
int find_bound_string (struct data_string *value,
4354
struct binding_scope *scope,
4357
struct binding *binding;
4359
binding = find_binding (scope, name);
4361
!binding -> value ||
4362
binding -> value -> type != binding_data)
4365
if (binding -> value -> value.data.terminated) {
4366
data_string_copy (value, &binding -> value -> value.data, MDL);
4368
buffer_allocate (&value -> buffer,
4369
binding -> value -> value.data.len,
4371
if (!value -> buffer)
4374
memcpy (value -> buffer -> data,
4375
binding -> value -> value.data.data,
4376
binding -> value -> value.data.len);
4377
value -> data = value -> buffer -> data;
4378
value -> len = binding -> value -> value.data.len;
4384
int unset (struct binding_scope *scope, const char *name)
4386
struct binding *binding;
4388
binding = find_binding (scope, name);
4390
if (binding -> value)
4391
binding_value_dereference
4392
(&binding -> value, MDL);
4398
/* vim: set tabstop=8: */