#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"
* 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
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))
#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;
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:
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:
int s0, s1, s2, s3;
int status;
struct binding *binding;
- char *s;
+ unsigned char *s;
struct binding_value *bv;
switch (expr -> op) {
return 1;
return 0;
-
/* Extract the last N bytes of a data string. */
case expr_suffix:
memset (&data, 0, sizeof data);
#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)
case expr_substring:
case expr_suffix:
+ case expr_lcase:
+ case expr_ucase:
case expr_option:
case expr_hardware:
case expr_const_data:
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);
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)
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:
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:
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:
}
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]);