diff options
author | David Hankins <dhankins@isc.org> | 2006-05-11 16:31:29 +0000 |
---|---|---|
committer | David Hankins <dhankins@isc.org> | 2006-05-11 16:31:29 +0000 |
commit | 2727c1cf8ffc0a34ea7059d36c30691e64cf8a46 (patch) | |
tree | 961fdc93887c8dc9451822cd5b33dccd3e5855c5 /common | |
parent | 509df655d1e4497a8b8c124bda277a541f9f4508 (diff) | |
download | isc-dhcp-2727c1cf8ffc0a34ea7059d36c30691e64cf8a46.tar.gz |
- lcase() and ucase() configuration expressions have been added which adjust
their arguments from upper to lower and lower to upper cases respectively.
[ISC-Bugs #1597]
Diffstat (limited to 'common')
-rw-r--r-- | common/conflex.c | 6 | ||||
-rw-r--r-- | common/dhcp-eval.5 | 19 | ||||
-rw-r--r-- | common/parse.c | 43 | ||||
-rw-r--r-- | common/print.c | 26 | ||||
-rw-r--r-- | common/tree.c | 163 |
5 files changed, 228 insertions, 29 deletions
diff --git a/common/conflex.c b/common/conflex.c index 55b8face..2dd8b897 100644 --- a/common/conflex.c +++ b/common/conflex.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: conflex.c,v 1.96 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: conflex.c,v 1.97 2006/05/11 16:31:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -805,6 +805,8 @@ static enum dhcp_token intern (atom, dfv) return KEY; break; case 'l': + if (!strcasecmp (atom + 1, "case")) + return LCASE; if (!strcasecmp (atom + 1, "ease")) return LEASE; if (!strcasecmp (atom + 1, "eased-address")) @@ -1071,6 +1073,8 @@ static enum dhcp_token intern (atom, dfv) return TRANSMISSION; break; case 'u': + if (!strcasecmp (atom + 1, "case")) + return UCASE; if (!strcasecmp (atom + 1, "nset")) return UNSET; if (!strcasecmp (atom + 1, "nsigned")) diff --git a/common/dhcp-eval.5 b/common/dhcp-eval.5 index 14c9e650..f7c0fde5 100644 --- a/common/dhcp-eval.5 +++ b/common/dhcp-eval.5 @@ -1,4 +1,4 @@ -.\" $Id: dhcp-eval.5,v 1.20 2006/05/05 20:32:30 dhankins Exp $ +.\" $Id: dhcp-eval.5,v 1.21 2006/05/11 16:31:29 dhankins Exp $ .\" .\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") .\" Copyright (c) 1996-2003 by Internet Software Consortium @@ -204,6 +204,22 @@ number greater than the length of the evaluated data, then the evaluated data is returned. .RE .PP +.B lcase (\fIdata-expr\fB)\fR +.PP +.RS 0.25i +The \fBlcase\fR function returns the result of evaluating +\fIdata-expr\fR converted to lower case. If \fIdata-expr\fR evaluates +to null, then the result is also null. +.RE +.PP +.B ucase (\fIdata-expr\fB)\fR +.PP +.RS 0.25i +The \fBucase\fR function returns the result of evaluating +\fIdata-expr\fR converted to upper case. If \fIdata-expr\fR evaluates +to null, then the result is also null. +.RE +.PP .B option \fIoption-name\fR .PP .RS 0.25i @@ -310,6 +326,7 @@ client, one could write the following expression: ".in-addr.arpa."); .fi +.RE .PP .B encode-int (\fInumeric-expr\fB, \fIwidth\fB)\fR .RS 0.25i diff --git a/common/parse.c b/common/parse.c index 9882c150..8aefd5d6 100644 --- a/common/parse.c +++ b/common/parse.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: parse.c,v 1.107 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: parse.c,v 1.108 2006/05/11 16:31:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -2684,9 +2684,11 @@ int parse_boolean_expression (expr, cfile, lose) * numeric-expression COMMA * numeric-expression RPAREN | * CONCAT LPAREN data-expression COMMA - data-expression RPAREN + * data-expression RPAREN * SUFFIX LPAREN data_expression COMMA * numeric-expression RPAREN | + * LCASE LPAREN data_expression RPAREN | + * UCASE LPAREN data_expression RPAREN | * OPTION option_name | * HARDWARE | * PACKET LPAREN numeric-expression COMMA @@ -3002,6 +3004,43 @@ int parse_non_binary (expr, cfile, lose, context) goto norparen; break; + case LCASE: + token = next_token(&val, (unsigned *)0, cfile); + if (!expression_allocate(expr, MDL)) + log_fatal ("can't allocate expression"); + (*expr)->op = expr_lcase; + + token = next_token(&val, (unsigned *)0, cfile); + if (token != LPAREN) + goto nolparen; + + if (!parse_data_expression(&(*expr)->data.lcase, cfile, lose)) + goto nodata; + + token = next_token(&val, (unsigned *)0, cfile); + if (token != RPAREN) + goto norparen; + break; + + case UCASE: + token = next_token(&val, (unsigned *)0, cfile); + if (!expression_allocate(expr, MDL)) + log_fatal ("can't allocate expression"); + (*expr)->op = expr_ucase; + + token = next_token (&val, (unsigned *)0, cfile); + if (token != LPAREN) + goto nolparen; + + if (!parse_data_expression(&(*expr)->data.ucase, + cfile, lose)) + goto nodata; + + token = next_token(&val, (unsigned *)0, cfile); + if (token != RPAREN) + goto norparen; + break; + case CONCAT: token = next_token (&val, (unsigned *)0, cfile); if (!expression_allocate (expr, MDL)) diff --git a/common/print.c b/common/print.c index 60e029b7..67f22837 100644 --- a/common/print.c +++ b/common/print.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: print.c,v 1.58 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: print.c,v 1.59 2006/05/11 16:31:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -550,6 +550,30 @@ static unsigned print_subexpression (expr, buf, len) } break; + case expr_lcase: + if (len > 9) { + rv = 7; + strcpy(buf, "(lcase "); + rv += print_subexpression(expr->data.lcase, + buf + rv, len - rv - 1); + buf[rv++] = ')'; + buf[rv] = 0; + return rv; + } + break; + + case expr_ucase: + if (len > 9) { + rv = 7; + strcpy(buf, "(ucase "); + rv += print_subexpression(expr->data.ucase, + buf + rv, len - rv - 1); + buf[rv++] = ')'; + buf[rv] = 0; + return rv; + } + break; + case expr_concat: if (len > 10) { rv = 8; diff --git a/common/tree.c b/common/tree.c index e1988641..a572b8d9 100644 --- a/common/tree.c +++ b/common/tree.c @@ -34,11 +34,12 @@ #ifndef lint static char copyright[] = -"$Id: tree.c,v 1.104 2006/02/24 23:16:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: tree.c,v 1.105 2006/05/11 16:31:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" #include <omapip/omapip_p.h> +#include <ctype.h> struct binding_scope *global_scope; @@ -835,6 +836,8 @@ int evaluate_dns_expression (result, packet, lease, client_state, in_options, case expr_none: case expr_substring: case expr_suffix: + case expr_lcase: + case expr_ucase: case expr_option: case expr_hardware: case expr_const_data: @@ -1198,6 +1201,8 @@ int evaluate_boolean_expression (result, packet, lease, client_state, case expr_match: case expr_substring: case expr_suffix: + case expr_lcase: + case expr_ucase: case expr_option: case expr_hardware: case expr_const_data: @@ -1279,7 +1284,7 @@ int evaluate_data_expression (result, packet, lease, client_state, int s0, s1, s2, s3; int status; struct binding *binding; - char *s; + unsigned char *s; struct binding_value *bv; switch (expr -> op) { @@ -1333,7 +1338,6 @@ int evaluate_data_expression (result, packet, lease, client_state, return 1; return 0; - /* Extract the last N bytes of a data string. */ case expr_suffix: memset (&data, 0, sizeof data); @@ -1372,6 +1376,78 @@ int evaluate_data_expression (result, packet, lease, client_state, #endif return s0 && s1; + /* Convert string to lowercase. */ + case expr_lcase: + memset(&data, 0, sizeof data); + s0 = evaluate_data_expression(&data, packet, lease, + client_state, + in_options, cfg_options, scope, + expr->data.lcase, MDL); + s1 = 0; + if (s0) { + result->len = data.len; + if (buffer_allocate(&result->buffer, + result->len + data.terminated, + MDL)) { + result->data = &result->buffer->data[0]; + memcpy(result->buffer->data, data.data, + data.len + data.terminated); + result->terminated = data.terminated; + s = (unsigned char *)result->data; + for (i = 0; i < result->len; i++, s++) + *s = tolower(*s); + s1 = 1; + } else { + log_error("data: lcase: no buffer memory."); + } + } + +#if defined (DEBUG_EXPRESSIONS) + log_debug("data: lcase (%s) = %s", + s0 ? print_hex_1(data.len, data.data, 30) : "NULL", + s1 ? print_hex_2(result->len, result->data, 30) + : "NULL"); +#endif + if (s0) + data_string_forget(&data, MDL); + return s1; + + /* Convert string to uppercase. */ + case expr_ucase: + memset(&data, 0, sizeof data); + s0 = evaluate_data_expression(&data, packet, lease, + client_state, + in_options, cfg_options, scope, + expr->data.lcase, MDL); + s1 = 0; + if (s0) { + result->len = data.len; + if (buffer_allocate(&result->buffer, + result->len + data.terminated, + file, line)) { + result->data = &result->buffer->data[0]; + memcpy(result->buffer->data, data.data, + data.len + data.terminated); + result->terminated = data.terminated; + s = (unsigned char *)result->data; + for (i = 0; i < result->len; i++, s++) + *s = toupper(*s); + s1 = 1; + } else { + log_error("data: lcase: no buffer memory."); + } + } + +#if defined (DEBUG_EXPRESSIONS) + log_debug("data: ucase (%s) = %s", + s0 ? print_hex_1(data.len, data.data, 30) : "NULL", + s1 ? print_hex_2(result->len, result->data, 30) + : "NULL"); +#endif + if (s0) + data_string_forget(&data, MDL); + return s1; + /* Extract an option. */ case expr_option: if (in_options) @@ -2164,6 +2240,8 @@ int evaluate_numeric_expression (result, packet, lease, client_state, case expr_substring: case expr_suffix: + case expr_lcase: + case expr_ucase: case expr_option: case expr_hardware: case expr_const_data: @@ -2799,6 +2877,16 @@ void expression_dereference (eptr, file, line) file, line); break; + case expr_lcase: + if (expr->data.lcase) + expression_dereference(&expr->data.lcase, MDL); + break; + + case expr_ucase: + if (expr->data.ucase) + expression_dereference(&expr->data.ucase, MDL); + break; + case expr_not: if (expr -> data.not) expression_dereference (&expr -> data.not, file, line); @@ -2979,27 +3067,29 @@ int is_boolean_expression (expr) int is_data_expression (expr) struct expression *expr; { - return (expr -> op == expr_substring || - expr -> op == expr_suffix || - expr -> op == expr_option || - expr -> op == expr_hardware || - expr -> op == expr_const_data || - expr -> op == expr_packet || - expr -> op == expr_concat || - expr -> op == expr_encapsulate || - expr -> op == expr_encode_int8 || - expr -> op == expr_encode_int16 || - expr -> op == expr_encode_int32 || - expr -> op == expr_host_lookup || - expr -> op == expr_binary_to_ascii || - expr -> op == expr_filename || - expr -> op == expr_sname || - expr -> op == expr_reverse || - expr -> op == expr_pick_first_value || - expr -> op == expr_host_decl_name || - expr -> op == expr_leased_address || - expr -> op == expr_config_option || - expr -> op == expr_null); + return (expr->op == expr_substring || + expr->op == expr_suffix || + expr->op == expr_lcase || + expr->op == expr_ucase || + expr->op == expr_option || + expr->op == expr_hardware || + expr->op == expr_const_data || + expr->op == expr_packet || + expr->op == expr_concat || + expr->op == expr_encapsulate || + expr->op == expr_encode_int8 || + expr->op == expr_encode_int16 || + expr->op == expr_encode_int32 || + expr->op == expr_host_lookup || + expr->op == expr_binary_to_ascii || + expr->op == expr_filename || + expr->op == expr_sname || + expr->op == expr_reverse || + expr->op == expr_pick_first_value || + expr->op == expr_host_decl_name || + expr->op == expr_leased_address || + expr->op == expr_config_option || + expr->op == expr_null); } int is_numeric_expression (expr) @@ -3058,6 +3148,8 @@ static int op_val (op) case expr_check: case expr_substring: case expr_suffix: + case expr_lcase: + case expr_ucase: case expr_concat: case expr_encapsulate: case expr_host_lookup: @@ -3154,6 +3246,8 @@ enum expression_context op_context (op) case expr_check: case expr_substring: case expr_suffix: + case expr_lcase: + case expr_ucase: case expr_concat: case expr_encapsulate: case expr_host_lookup: @@ -3289,6 +3383,21 @@ int write_expression (file, expr, col, indent, firstp) col = write_expression (file, expr -> data.suffix.len, col, scol, 0); col = token_print_indent (file, col, indent, "", "", ")"); + + case expr_lcase: + col = token_print_indent(file, col, indent, "", "", "lcase"); + col = token_print_indent(file, col, indent, " ", "", "("); + scol = col; + col = write_expression(file, expr->data.lcase, col, scol, 1); + col = token_print_indent(file, col, indent, "", "", ")"); + break; + + case expr_ucase: + col = token_print_indent(file, col, indent, "", "", "ucase"); + col = token_print_indent(file, col, indent, " ", "", "("); + scol = col; + col = write_expression(file, expr->data.ucase, col, scol, 1); + col = token_print_indent(file, col, indent, "", "", ")"); break; case expr_concat: @@ -3857,6 +3966,12 @@ int data_subexpression_length (int *rv, } return 0; + case expr_lcase: + return data_subexpression_length(rv, expr->data.lcase); + + case expr_ucase: + return data_subexpression_length(rv, expr->data.ucase); + case expr_concat: clhs = data_subexpression_length (&llhs, expr -> data.concat [0]); |