From 17638a8659a41501bf143dc78ada84a15cb9de6a Mon Sep 17 00:00:00 2001 From: deraadt <> Date: Tue, 11 Sep 2007 23:33:37 +0000 Subject: [PATCH] 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 --- src/usr.sbin/ntpd/parse.y | 98 +++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 24 deletions(-) diff --git a/src/usr.sbin/ntpd/parse.y b/src/usr.sbin/ntpd/parse.y index 9e106415..bc8902ca 100644 --- a/src/usr.sbin/ntpd/parse.y +++ b/src/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 @@ -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 STRING +%token NUMBER %type address -%type number weight +%type server_opts server_opts_l server_opt +%type sensor_opts sensor_opts_l sensor_opt +%type 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 != '>' && \