mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-02 15:25:48 +00:00
- Add support for a timezone offset in lease file (possibly useless).
- Add support for concat data subexpression. - Add support for specifying option data as a data expression instead of in the option's specified format.
This commit is contained in:
123
common/parse.c
123
common/parse.c
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: parse.c,v 1.21 1999/04/12 22:09:24 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: parse.c,v 1.22 1999/05/06 20:20:43 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -533,11 +533,14 @@ void convert_num (buf, str, base, size)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
|
* date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
|
||||||
* NUMBER COLON NUMBER COLON NUMBER SEMI
|
* NUMBER COLON NUMBER COLON NUMBER SEMI |
|
||||||
|
* NUMBER NUMBER SLASH NUMBER SLASH NUMBER
|
||||||
|
* NUMBER COLON NUMBER COLON NUMBER NUMBER SEMI |
|
||||||
*
|
*
|
||||||
* Dates are always in GMT; first number is day of week; next is
|
* Dates are stored in GMT or with a timezone offset; first number is day
|
||||||
* year/month/day; next is hours:minutes:seconds on a 24-hour
|
* of week; next is year/month/day; next is hours:minutes:seconds on a
|
||||||
* clock.
|
* 24-hour clock, followed by the timezone offset in seconds, which is
|
||||||
|
* optional.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TIME parse_date (cfile)
|
TIME parse_date (cfile)
|
||||||
@@ -545,6 +548,7 @@ TIME parse_date (cfile)
|
|||||||
{
|
{
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
int guess;
|
int guess;
|
||||||
|
int tzoff, wday, year, mon, mday, hour, min, sec;
|
||||||
char *val;
|
char *val;
|
||||||
enum dhcp_token token;
|
enum dhcp_token token;
|
||||||
static int months [11] = { 31, 59, 90, 120, 151, 181,
|
static int months [11] = { 31, 59, 90, 120, 151, 181,
|
||||||
@@ -558,7 +562,7 @@ TIME parse_date (cfile)
|
|||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (TIME)0;
|
return (TIME)0;
|
||||||
}
|
}
|
||||||
tm.tm_wday = atoi (val);
|
wday = atoi (val);
|
||||||
|
|
||||||
/* Year... */
|
/* Year... */
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@@ -573,9 +577,9 @@ TIME parse_date (cfile)
|
|||||||
somebody invents a time machine, I think we can safely disregard
|
somebody invents a time machine, I think we can safely disregard
|
||||||
it. This actually works around a stupid Y2K bug that was present
|
it. This actually works around a stupid Y2K bug that was present
|
||||||
in a very early beta release of dhcpd. */
|
in a very early beta release of dhcpd. */
|
||||||
tm.tm_year = atoi (val);
|
year = atoi (val);
|
||||||
if (tm.tm_year > 1900)
|
if (year > 1900)
|
||||||
tm.tm_year -= 1900;
|
year -= 1900;
|
||||||
|
|
||||||
/* Slash seperating year from month... */
|
/* Slash seperating year from month... */
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@@ -594,7 +598,7 @@ TIME parse_date (cfile)
|
|||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (TIME)0;
|
return (TIME)0;
|
||||||
}
|
}
|
||||||
tm.tm_mon = atoi (val) - 1;
|
mon = atoi (val) - 1;
|
||||||
|
|
||||||
/* Slash seperating month from day... */
|
/* Slash seperating month from day... */
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@@ -613,7 +617,7 @@ TIME parse_date (cfile)
|
|||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (TIME)0;
|
return (TIME)0;
|
||||||
}
|
}
|
||||||
tm.tm_mday = atoi (val);
|
mday = atoi (val);
|
||||||
|
|
||||||
/* Hour... */
|
/* Hour... */
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@@ -623,7 +627,7 @@ TIME parse_date (cfile)
|
|||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (TIME)0;
|
return (TIME)0;
|
||||||
}
|
}
|
||||||
tm.tm_hour = atoi (val);
|
hour = atoi (val);
|
||||||
|
|
||||||
/* Colon seperating hour from minute... */
|
/* Colon seperating hour from minute... */
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@@ -642,7 +646,7 @@ TIME parse_date (cfile)
|
|||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (TIME)0;
|
return (TIME)0;
|
||||||
}
|
}
|
||||||
tm.tm_min = atoi (val);
|
min = atoi (val);
|
||||||
|
|
||||||
/* Colon seperating minute from second... */
|
/* Colon seperating minute from second... */
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
@@ -661,27 +665,30 @@ TIME parse_date (cfile)
|
|||||||
skip_to_semi (cfile);
|
skip_to_semi (cfile);
|
||||||
return (TIME)0;
|
return (TIME)0;
|
||||||
}
|
}
|
||||||
tm.tm_sec = atoi (val);
|
sec = atoi (val);
|
||||||
tm.tm_isdst = 0;
|
|
||||||
|
|
||||||
/* XXX */ /* We assume that mktime does not use tm_yday. */
|
token = peek_token (&val, cfile);
|
||||||
tm.tm_yday = 0;
|
if (token == NUMBER) {
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
tzoff = atoi (val);
|
||||||
|
} else
|
||||||
|
tzoff = 0;
|
||||||
|
|
||||||
/* Make sure the date ends in a semicolon... */
|
/* Make sure the date ends in a semicolon... */
|
||||||
if (!parse_semi (cfile))
|
if (!parse_semi (cfile))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Guess the time value... */
|
/* Guess the time value... */
|
||||||
guess = ((((((365 * (tm.tm_year - 70) + /* Days in years since '70 */
|
guess = ((((((365 * (year - 70) + /* Days in years since '70 */
|
||||||
(tm.tm_year - 69) / 4 + /* Leap days since '70 */
|
(year - 69) / 4 + /* Leap days since '70 */
|
||||||
(tm.tm_mon /* Days in months this year */
|
(mon /* Days in months this year */
|
||||||
? months [tm.tm_mon - 1]
|
? months [mon - 1]
|
||||||
: 0) +
|
: 0) +
|
||||||
(tm.tm_mon > 1 && /* Leap day this year */
|
(mon > 1 && /* Leap day this year */
|
||||||
!((tm.tm_year - 72) & 3)) +
|
!((year - 72) & 3)) +
|
||||||
tm.tm_mday - 1) * 24) + /* Day of month */
|
mday - 1) * 24) + /* Day of month */
|
||||||
tm.tm_hour) * 60) +
|
hour) * 60) +
|
||||||
tm.tm_min) * 60) + tm.tm_sec;
|
min) * 60) + sec + tzoff;
|
||||||
|
|
||||||
/* This guess could be wrong because of leap seconds or other
|
/* This guess could be wrong because of leap seconds or other
|
||||||
weirdness we don't know about that the system does. For
|
weirdness we don't know about that the system does. For
|
||||||
@@ -1413,8 +1420,10 @@ int parse_boolean_expression (expr, cfile, lose)
|
|||||||
* data_expression :== SUBSTRING LPAREN data-expression COMMA
|
* data_expression :== SUBSTRING LPAREN data-expression COMMA
|
||||||
* numeric-expression COMMA
|
* numeric-expression COMMA
|
||||||
* numeric-expression RPAREN |
|
* numeric-expression RPAREN |
|
||||||
|
* CONCAT LPAREN data-expression COMMA
|
||||||
|
data-expression RPAREN
|
||||||
* SUFFIX LPAREN data_expression COMMA
|
* SUFFIX LPAREN data_expression COMMA
|
||||||
* numeric-expression |
|
* numeric-expression RPAREN |
|
||||||
* OPTION option_name |
|
* OPTION option_name |
|
||||||
* HARDWARE |
|
* HARDWARE |
|
||||||
* PACKET LPAREN numeric-expression COMMA
|
* PACKET LPAREN numeric-expression COMMA
|
||||||
@@ -1640,6 +1649,33 @@ int parse_non_binary (expr, cfile, lose, context)
|
|||||||
goto norparen;
|
goto norparen;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CONCAT:
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (!expression_allocate (expr, "parse_expression: CONCAT"))
|
||||||
|
log_fatal ("can't allocate expression");
|
||||||
|
(*expr) -> op = expr_concat;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != LPAREN)
|
||||||
|
goto nolparen;
|
||||||
|
|
||||||
|
if (!parse_data_expression (&(*expr) -> data.concat [0],
|
||||||
|
cfile, lose))
|
||||||
|
goto nodata;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != COMMA)
|
||||||
|
goto nocomma;
|
||||||
|
|
||||||
|
if (!parse_data_expression (&(*expr) -> data.concat [1],
|
||||||
|
cfile, lose))
|
||||||
|
goto nodata;
|
||||||
|
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
if (token != RPAREN)
|
||||||
|
goto norparen;
|
||||||
|
break;
|
||||||
|
|
||||||
case OPTION:
|
case OPTION:
|
||||||
token = next_token (&val, cfile);
|
token = next_token (&val, cfile);
|
||||||
if (!expression_allocate (expr, "parse_expression: OPTION"))
|
if (!expression_allocate (expr, "parse_expression: OPTION"))
|
||||||
@@ -1963,6 +1999,26 @@ struct executable_statement *parse_option_statement (cfile, lookups,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token == EQUAL) {
|
||||||
|
/* Eat the equals sign. */
|
||||||
|
token = next_token (&val, cfile);
|
||||||
|
|
||||||
|
/* Parse a data expression and use its value for the data. */
|
||||||
|
if (!parse_data_expression (&expr, cfile, &lose)) {
|
||||||
|
/* In this context, we must have an executable
|
||||||
|
statement, so if we found something else, it's
|
||||||
|
still an error. */
|
||||||
|
if (!lose) {
|
||||||
|
parse_warn ("expecting a data expression.");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
}
|
||||||
|
return (struct executable_statement *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We got a valid expression, so use it. */
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the option data... */
|
/* Parse the option data... */
|
||||||
do {
|
do {
|
||||||
/* Set a flag if this is an array of a simple type (i.e.,
|
/* Set a flag if this is an array of a simple type (i.e.,
|
||||||
@@ -1995,19 +2051,6 @@ struct executable_statement *parse_option_statement (cfile, lookups,
|
|||||||
}
|
}
|
||||||
} while (*fmt == 'A');
|
} while (*fmt == 'A');
|
||||||
|
|
||||||
#if 0
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
try_expr:
|
|
||||||
/* See if there's a data expression, and if so, use it rather than
|
|
||||||
the standard format. */
|
|
||||||
expr = parse_data_expression (cfile, &lose);
|
|
||||||
|
|
||||||
/* Found a data expression, but it was bogus? */
|
|
||||||
if (lose)
|
|
||||||
return (struct executable_statement *)0;
|
|
||||||
|
|
||||||
#endif /* 0 */
|
|
||||||
done:
|
done:
|
||||||
if (!parse_semi (cfile))
|
if (!parse_semi (cfile))
|
||||||
return (struct executable_statement *)0;
|
return (struct executable_statement *)0;
|
||||||
|
Reference in New Issue
Block a user