summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-09-11 23:33:38 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-09-11 23:33:38 +0000
commit1035d13d98f5bad5f1361dad01ad9296d7ad868e (patch)
treeebdf414f772821b342b1658596376f25d4c25caa
parent9b985ce0f6e0e2d64505e198c81bb3dc50e6892a (diff)
this is where it all started, since future ntpd.conf commands will require
negative parameters. extend lex to spot numbers in the stream. as well, make it easier to add parameters on command line in any order later ok otto ckuethe
-rw-r--r--usr.sbin/ntpd/parse.y98
1 files changed, 74 insertions, 24 deletions
diff --git a/usr.sbin/ntpd/parse.y b/usr.sbin/ntpd/parse.y
index 9e106415301..bc8902cad45 100644
--- a/usr.sbin/ntpd/parse.y
+++ b/usr.sbin/ntpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.30 2006/10/03 00:49:09 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.31 2007/09/11 23:33:37 deraadt Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -51,11 +51,16 @@ int lungetc(int);
int findeol(void);
int yylex(void);
+struct opts {
+ int weight;
+} opts;
+
typedef struct {
union {
- u_int32_t number;
+ int64_t number;
char *string;
struct ntp_addr_wrap *addr;
+ struct opts opts;
} v;
int lineno;
} YYSTYPE;
@@ -66,8 +71,11 @@ typedef struct {
%token SERVER SERVERS SENSOR WEIGHT
%token ERROR
%token <v.string> STRING
+%token <v.number> NUMBER
%type <v.addr> address
-%type <v.number> number weight
+%type <v.opts> server_opts server_opts_l server_opt
+%type <v.opts> sensor_opts sensor_opts_l sensor_opt
+%type <v.opts> weight
%%
grammar : /* empty */
@@ -108,7 +116,7 @@ conf_main : LISTEN ON address {
free($3->name);
free($3);
}
- | SERVERS address weight {
+ | SERVERS address server_opts {
struct ntp_peer *p;
struct ntp_addr *h, *next;
@@ -130,7 +138,7 @@ conf_main : LISTEN ON address {
next = NULL;
p = new_peer();
- p->weight = $3;
+ p->weight = $3.weight;
p->addr = h;
p->addr_head.a = h;
p->addr_head.pool = 1;
@@ -147,7 +155,7 @@ conf_main : LISTEN ON address {
free($2->name);
free($2);
}
- | SERVER address weight {
+ | SERVER address server_opts {
struct ntp_peer *p;
struct ntp_addr *h, *next;
@@ -168,7 +176,7 @@ conf_main : LISTEN ON address {
p->addr = h;
}
- p->weight = $3;
+ p->weight = $3.weight;
p->addr_head.a = p->addr;
p->addr_head.pool = 0;
p->addr_head.name = strdup($2->name);
@@ -180,11 +188,11 @@ conf_main : LISTEN ON address {
free($2->name);
free($2);
}
- | SENSOR STRING weight {
+ | SENSOR STRING sensor_opts {
struct ntp_conf_sensor *s;
s = new_sensor($2);
- s->weight = $3;
+ s->weight = $3.weight;
free($2);
TAILQ_INSERT_TAIL(&conf->ntp_conf_sensors, s, entry);
}
@@ -205,28 +213,34 @@ address : STRING {
}
;
-number : STRING {
- u_long ulval;
- const char *errstr;
+server_opts : { bzero(&opts, sizeof opts); }
+ server_opts_l
+ { $$ = opts; }
+ | { bzero(&opts, sizeof opts); $$ = opts; }
+ ;
+server_opts_l : server_opts_l server_opt
+ | server_opt
+ ;
+server_opt : weight
+ ;
- ulval = strtonum($1, 0, INT_MAX, &errstr);
- if (errstr) {
- yyerror("\"%s\" invalid: %s", $1, errstr);
- free($1);
- YYERROR;
- } else
- $$ = ulval;
- free($1);
- }
+sensor_opts : { bzero(&opts, sizeof opts); }
+ sensor_opts_l
+ { $$ = opts; }
+ | { bzero(&opts, sizeof opts); $$ = opts; }
+ ;
+sensor_opts_l : sensor_opts_l sensor_opt
+ | sensor_opt
+ ;
+sensor_opt : weight
;
-weight : /* empty */ { $$ = 1; }
- | WEIGHT number {
+weight : WEIGHT NUMBER {
if ($2 < 1 || $2 > 10) {
yyerror("weight must be between 1 and 10");
YYERROR;
}
- $$ = $2;
+ opts.weight = $2;
}
;
@@ -410,6 +424,42 @@ yylex(void)
return (STRING);
}
+#define allowed_to_end_number(x) \
+ (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}')
+
+ if (c == '-' || isdigit(c)) {
+ do {
+ *p++ = c;
+ if ((unsigned)(p-buf) >= sizeof(buf)) {
+ yyerror("string too long");
+ return (findeol());
+ }
+ } while ((c = lgetc(fin)) != EOF && isdigit(c));
+ lungetc(c);
+ if (p == buf + 1 && buf[0] == '-')
+ goto nodigits;
+ if (c == EOF || allowed_to_end_number(c)) {
+ const char *errstr = NULL;
+
+ *p = '\0';
+ yylval.v.number = strtonum(buf, LLONG_MIN,
+ LLONG_MAX, &errstr);
+ if (errstr) {
+ yyerror("\"%s\" invalid number: %s",
+ buf, errstr);
+ return (findeol());
+ }
+ return (NUMBER);
+ } else {
+nodigits:
+ while (p > buf + 1)
+ lungetc(*--p);
+ c = *--p;
+ if (c == '-')
+ return (c);
+ }
+ }
+
#define allowed_in_string(x) \
(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
x != '{' && x != '}' && x != '<' && x != '>' && \