/* * Copyright (C) 2017-2022 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Internet Systems Consortium, Inc. * PO Box 360 * Newmarket, NH 03857 USA * * https://www.isc.org/ * */ #include "keama.h" #include #include #include #include #include #include #include #include #include static void debug(const char* fmt, ...); const char * print_expression(struct element *expr, isc_boolean_t *lose) { if (expr->type == ELEMENT_BOOLEAN) return print_boolean_expression(expr, lose); if (expr->type == ELEMENT_INTEGER) return print_numeric_expression(expr, lose); if (expr->type == ELEMENT_STRING) return print_data_expression(expr, lose); if (is_boolean_expression(expr)) return print_boolean_expression(expr, lose); if (is_numeric_expression(expr)) return print_numeric_expression(expr, lose); if (is_data_expression(expr)) return print_data_expression(expr, lose); *lose = ISC_TRUE; return "???"; } const char * print_boolean_expression(struct element *expr, isc_boolean_t *lose) { struct string *result; if (expr->type == ELEMENT_BOOLEAN) { if (boolValue(expr)) return "true"; else return "false"; } /* * From is_boolean_expression */ if (expr->type != ELEMENT_MAP) { *lose = ISC_TRUE; return "???"; } result = allocString(); /* check */ if (mapContains(expr, "check")) { struct element *name; appendString(result, "check "); name = mapGet(expr, "check"); if ((name == NULL) || (name->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); } else concatString(result, stringValue(name)); return result->content; } /* exists */ if (mapContains(expr, "exists")) { struct element *arg; struct element *universe; struct element *name; appendString(result, "exists "); arg = mapGet(expr, "exists"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } universe = mapGet(arg, "universe"); if ((universe == NULL) || (universe->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } concatString(result, stringValue(universe)); appendString(result, "."); name = mapGet(arg, "name"); if ((name == NULL) || (name->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } concatString(result, stringValue(name)); return result->content; } /* variable-exists */ if (mapContains(expr, "variable-exists")) { struct element *name; appendString(result, "variable-exists "); name = mapGet(expr, "variable-exists"); if ((name == NULL) || (name->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); } else concatString(result, stringValue(name)); return result->content; } /* equal */ if (mapContains(expr, "equal")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "equal "); arg = mapGet(expr, "equal"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_equal, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " = "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_equal, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* not-equal */ if (mapContains(expr, "not-equal")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "not-equal "); arg = mapGet(expr, "not-equal"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_not_equal, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " != "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_not_equal, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* regex-match */ if (mapContains(expr, "regex-match")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "regex-match "); arg = mapGet(expr, "regex-match"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_regex_match, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " ~= "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } appendString(result, print_expression(right, lose)); return result->content; } /* iregex-match */ if (mapContains(expr, "iregex-match")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "iregex-match "); arg = mapGet(expr, "iregex-match"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_iregex_match, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " ~~ "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } appendString(result, print_expression(right, lose)); return result->content; } /* and */ if (mapContains(expr, "and")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "and "); arg = mapGet(expr, "and"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_and, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " and "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_and, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* or */ if (mapContains(expr, "or")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "or "); arg = mapGet(expr, "or"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_or, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " or "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_or, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* not */ if (mapContains(expr, "not")) { struct element *arg; isc_boolean_t add_parenthesis; appendString(result, "not "); arg = mapGet(expr, "not"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_not, arg) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(arg, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* known */ if (mapContains(expr, "known")) { return "known"; } /* static */ if (mapContains(expr, "static")) { return "static"; } /* variable-reference */ if (mapContains(expr, "variable-reference")) { struct element *name; appendString(result, "variable-reference "); name = mapGet(expr, "variable-reference"); if ((name == NULL) || (name->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } return stringValue(name)->content; } /* funcall */ if (mapContains(expr, "funcall")) { struct element *arg; struct element *name; struct element *args; size_t i; appendString(result, "funcall "); arg = mapGet(expr, "funcall"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } name = mapGet(arg, "name"); if ((name == NULL) || (name->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); concatString(result, stringValue(name)); appendString(result, "("); args = mapGet(arg, "arguments"); if ((args == NULL) || (args->type != ELEMENT_LIST)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } for (i = 0; i < listSize(args); i++) { struct element *item; if (i != 0) appendString(result, ", "); item = listGet(args, i); if (item == NULL) { debug("funcall null argument %u", (unsigned)i); *lose = ISC_TRUE; appendString(result, "???"); continue; } appendString(result, print_expression(item, lose)); } appendString(result, ")"); return result->content; } *lose = ISC_TRUE; appendString(result, "???"); return result->content; } const char * print_data_expression(struct element *expr, isc_boolean_t *lose) { struct string *result; if (expr->type == ELEMENT_STRING) return quote(stringValue(expr))->content; /* * From is_data_expression */ if (expr->type != ELEMENT_MAP) { *lose = ISC_TRUE; return "???"; } result = allocString(); /* substring */ if (mapContains(expr, "substring")) { struct element *arg; struct element *string; struct element *offset; struct element *length; appendString(result, "substring("); arg = mapGet(expr, "substring"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } string = mapGet(arg, "expression"); if (string == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(string, lose)); appendString(result, ", "); offset = mapGet(arg, "offset"); if (offset == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(offset, lose)); appendString(result, ", "); length = mapGet(arg, "length"); if (length == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(length, lose)); appendString(result, ")"); return result->content; } /* suffix */ if (mapContains(expr, "suffix")) { struct element *arg; struct element *string; struct element *length; appendString(result, "suffix("); arg = mapGet(expr, "suffix"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } string = mapGet(arg, "expression"); if (string == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(string, lose)); appendString(result, ", "); length = mapGet(arg, "length"); if (length == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(length, lose)); appendString(result, ")"); return result->content; } /* lowercase */ if (mapContains(expr, "lowercase")) { struct element *arg; appendString(result, "lowercase("); arg = mapGet(expr, "lowercase"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(arg, lose)); appendString(result, ")"); return result->content; } /* uppercase */ if (mapContains(expr, "uppercase")) { struct element *arg; appendString(result, "uppercase("); arg = mapGet(expr, "uppercase"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(arg, lose)); appendString(result, ")"); return result->content; } /* option */ if (mapContains(expr, "option")) { struct element *arg; struct element *universe; struct element *name; appendString(result, "option "); arg = mapGet(expr, "option"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } universe = mapGet(arg, "universe"); if ((universe == NULL) || (universe->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } concatString(result, stringValue(universe)); appendString(result, "."); name = mapGet(arg, "name"); if ((name == NULL) || (name->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } concatString(result, stringValue(name)); return result->content; } /* hardware */ if (mapContains(expr, "hardware")) return "hardware"; /* hw-type */ if (mapContains(expr, "hw-type")) return "hw-type"; /* hw-address */ if (mapContains(expr, "hw-address")) return "hw-address"; /* const-data */ if (mapContains(expr, "const-data")) { struct element *arg; arg = mapGet(expr, "const-data"); if ((arg == NULL) || (arg->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } concatString(result, stringValue(arg)); return result->content; } /* packet */ if (mapContains(expr, "packet")) { struct element *arg; struct element *offset; struct element *length; appendString(result, "packet("); arg = mapGet(expr, "packet"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } offset = mapGet(arg, "offset"); if (offset == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(offset, lose)); appendString(result, ", "); length = mapGet(arg, "length"); if (length == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(length, lose)); appendString(result, ")"); return result->content; } /* concat */ if (mapContains(expr, "concat")) { struct element *arg; struct element *left; struct element *right; appendString(result, "concat("); arg = mapGet(expr, "concat"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(left, lose)); appendString(result, ", "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(right, lose)); appendString(result, ")"); return result->content; } /* encapsulate */ if (mapContains(expr, "encapsulate")) { struct element *arg; appendString(result, "encapsulate "); arg = mapGet(expr, "encapsulate"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } appendString(result, print_data_expression(arg, lose)); return result->content; } /* encode-int8 */ if (mapContains(expr, "encode-int8")) { struct element *arg; appendString(result, "encode-int("); arg = mapGet(expr, "encode-int8"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???, 8)"); return result->content; } appendString(result, print_numeric_expression(arg, lose)); appendString(result, ", 8)"); return result->content; } /* encode-int16 */ if (mapContains(expr, "encode-int16")) { struct element *arg; appendString(result, "encode-int("); arg = mapGet(expr, "encode-int16"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???, 16)"); return result->content; } appendString(result, print_numeric_expression(arg, lose)); appendString(result, ", 16)"); return result->content; } /* encode-int32 */ if (mapContains(expr, "encode-int32")) { struct element *arg; appendString(result, "encode-int("); arg = mapGet(expr, "encode-int32"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???, 32)"); return result->content; } appendString(result, print_numeric_expression(arg, lose)); appendString(result, ", 32)"); return result->content; } /* gethostbyname */ if (mapContains(expr, "gethostbyname")) { struct element *arg; appendString(result, "gethostbyname("); arg = mapGet(expr, "gethostbyname"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } appendString(result, print_data_expression(arg, lose)); appendString(result, ")"); return result->content; } /* binary-to-ascii */ if (mapContains(expr, "binary-to-ascii")) { struct element *arg; struct element *base; struct element *width; struct element *separator; struct element *buffer; appendString(result, "binary-to-ascii("); arg = mapGet(expr, "binary-to-ascii"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } base = mapGet(arg, "base"); if (base == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(base, lose)); appendString(result, ", "); width = mapGet(arg, "width"); if (width == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(width, lose)); appendString(result, ", "); separator = mapGet(arg, "separator"); if (separator == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(separator, lose)); appendString(result, ", "); buffer = mapGet(arg, "buffer"); if (buffer == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(buffer, lose)); appendString(result, ")"); return result->content; } /* filename */ if (mapContains(expr, "filename")) return "filename"; /* server-name */ if (mapContains(expr, "server-name")) return "server-name"; /* reverse */ if (mapContains(expr, "reverse")) { struct element *arg; struct element *width; struct element *buffer; appendString(result, "reverse("); arg = mapGet(expr, "reverse"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } width = mapGet(arg, "width"); if (width == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(width, lose)); appendString(result, ", "); buffer = mapGet(arg, "buffer"); if (buffer == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(buffer, lose)); appendString(result, ")"); return result->content; } /* pick-first-value */ if (mapContains(expr, "pick-first-value")) { struct element *arg; size_t i; appendString(result, "pick-first-value("); arg = mapGet(expr, "pick-first-value"); if ((arg == NULL) || (arg->type != ELEMENT_LIST)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } for (i = 0; i < listSize(arg); i++) { struct element *item; if (i != 0) appendString(result, ", "); item = listGet(arg, i); if (item == NULL) { *lose = ISC_TRUE; appendString(result, "???"); continue; } appendString(result, print_data_expression(item, lose)); } appendString(result, ")"); return result->content; } /* host-decl-name */ if (mapContains(expr, "host-decl-name")) return "host-decl-name"; /* leased-address */ if (mapContains(expr, "leased-address")) return "leased-address"; /* config-option */ if (mapContains(expr, "config-option")) { struct element *arg; struct element *universe; struct element *name; appendString(result, "config-option "); arg = mapGet(expr, "config-option"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } universe = mapGet(arg, "universe"); if ((universe == NULL) || (universe->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } concatString(result, stringValue(universe)); appendString(result, "."); name = mapGet(arg, "name"); if ((name == NULL) || (name->type != ELEMENT_STRING)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } concatString(result, stringValue(name)); return result->content; } /* null */ if (mapContains(expr, "null")) return "null"; /* gethostname */ if (mapContains(expr, "gethostname")) return "gethostname"; /* v6relay */ if (mapContains(expr, "v6relay")) { struct element *arg; struct element *relay; struct element *option; appendString(result, "v6relay("); arg = mapGet(expr, "v6relay"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } relay = mapGet(arg, "relay"); if (relay == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_numeric_expression(relay, lose)); appendString(result, ", "); option = mapGet(arg, "relay-option"); if (option == NULL) { *lose = ISC_TRUE; appendString(result, "???" ")"); return result->content; } appendString(result, print_data_expression(option, lose)); appendString(result, ")"); return result->content; } *lose = ISC_TRUE; appendString(result, "???"); return result->content; } const char * print_numeric_expression(struct element *expr, isc_boolean_t *lose) { struct string *result; if (expr->type == ELEMENT_INTEGER) { char buf[20]; snprintf(buf, sizeof(buf), "%lld", (long long)intValue(expr)); result = makeString(-1, buf); return result->content; } /* * From is_numeric_expression */ if (expr->type != ELEMENT_MAP) { *lose = ISC_TRUE; return "???"; } result = allocString(); /* extract-int8 */ if (mapContains(expr, "extract-int8")) { struct element *arg; appendString(result, "extract-int("); arg = mapGet(expr, "extract-int8"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???, 8)"); return result->content; } appendString(result, print_data_expression(arg, lose)); appendString(result, ", 8)"); return result->content; } /* extract-int16 */ if (mapContains(expr, "extract-int16")) { struct element *arg; appendString(result, "extract-int("); arg = mapGet(expr, "extract-int16"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???, 16)"); return result->content; } appendString(result, print_data_expression(arg, lose)); appendString(result, ", 16)"); return result->content; } /* extract-int32 */ if (mapContains(expr, "extract-int32")) { struct element *arg; appendString(result, "extract-int("); arg = mapGet(expr, "extract-int32"); if (arg == NULL) { *lose = ISC_TRUE; appendString(result, "???, 32)"); return result->content; } appendString(result, print_data_expression(arg, lose)); appendString(result, ", 32)"); return result->content; } /* const-int */ if (mapContains(expr, "const-int")) { struct element *arg; char buf[20]; arg = mapGet(expr, "const-int"); if ((arg == NULL) || (arg->type != ELEMENT_INTEGER)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } snprintf(buf, sizeof(buf), "%lld", (long long)intValue(arg)); result = makeString(-1, buf); return result->content; } /* lease-time */ if (mapContains(expr, "lease-time")) return "lease-time"; /* add */ if (mapContains(expr, "add")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "add "); arg = mapGet(expr, "add"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_add, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " + "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_add, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* subtract */ if (mapContains(expr, "subtract")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "subtract "); arg = mapGet(expr, "subtract"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_subtract, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " - "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_subtract, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* multiply */ if (mapContains(expr, "multiply")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "multiply "); arg = mapGet(expr, "multiply"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_multiply, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " * "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_multiply, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* divide */ if (mapContains(expr, "divide")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "divide "); arg = mapGet(expr, "divide"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_divide, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " / "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_divide, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* remainder */ if (mapContains(expr, "remainder")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "remainder "); arg = mapGet(expr, "remainder"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_remainder, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " % "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_remainder, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* binary-and */ if (mapContains(expr, "binary-and")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "binary-and "); arg = mapGet(expr, "binary-and"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_binary_and, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " & "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_binary_and, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* binary-or */ if (mapContains(expr, "binary-or")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "binary-or "); arg = mapGet(expr, "binary-or"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_binary_or, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " | "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_binary_or, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* binary-xor */ if (mapContains(expr, "binary-xor")) { struct element *arg; struct element *left; struct element *right; isc_boolean_t add_parenthesis; appendString(result, "binary-xor "); arg = mapGet(expr, "binary-xor"); if ((arg == NULL) || (arg->type != ELEMENT_MAP)) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } left = mapGet(arg, "left"); if (left == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } result = allocString(); add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor, left) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(left, lose)); if (add_parenthesis) appendString(result, ")"); appendString(result, " ^ "); right = mapGet(arg, "right"); if (right == NULL) { *lose = ISC_TRUE; appendString(result, "???"); return result->content; } add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor, right) < 0); if (add_parenthesis) appendString(result, "("); appendString(result, print_expression(right, lose)); if (add_parenthesis) appendString(result, ")"); return result->content; } /* client-state */ if (mapContains(expr, "client-state")) return "client-state"; *lose = ISC_TRUE; appendString(result, "???"); return result->content; } static void debug(const char* fmt, ...) { va_list list; va_start(list, fmt); vfprintf(stderr, fmt, list); fprintf(stderr, "\n"); va_end(list); }