GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ntpd/parse.c Lines: 0 290 0.0 %
Date: 2017-11-13 Branches: 0 227 0.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 23 "parse.y"
13
#include <sys/types.h>
14
#include <sys/socket.h>
15
#include <netinet/in.h>
16
#include <arpa/inet.h>
17
18
#include <ctype.h>
19
#include <errno.h>
20
#include <limits.h>
21
#include <stdarg.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <syslog.h>
26
27
#include "ntpd.h"
28
29
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
30
static struct file {
31
	TAILQ_ENTRY(file)	 entry;
32
	FILE			*stream;
33
	char			*name;
34
	int			 lineno;
35
	int			 errors;
36
} *file, *topfile;
37
struct file	*pushfile(const char *);
38
int		 popfile(void);
39
int		 yyparse(void);
40
int		 yylex(void);
41
int		 yyerror(const char *, ...)
42
    __attribute__((__format__ (printf, 1, 2)))
43
    __attribute__((__nonnull__ (1)));
44
int		 kw_cmp(const void *, const void *);
45
int		 lookup(char *);
46
int		 lgetc(int);
47
int		 lungetc(int);
48
int		 findeol(void);
49
50
struct ntpd_conf		*conf;
51
struct sockaddr_in		 query_addr4;
52
struct sockaddr_in6		 query_addr6;
53
54
struct opts {
55
	int		weight;
56
	int		correction;
57
	int		stratum;
58
	int		rtable;
59
	char		*refstr;
60
} opts;
61
void		opts_default(void);
62
63
typedef struct {
64
	union {
65
		int64_t			 number;
66
		char			*string;
67
		struct ntp_addr_wrap	*addr;
68
		struct opts		 opts;
69
	} v;
70
	int lineno;
71
} YYSTYPE;
72
73
#line 74 "parse.c"
74
#define LISTEN 257
75
#define ON 258
76
#define CONSTRAINT 259
77
#define CONSTRAINTS 260
78
#define FROM 261
79
#define QUERY 262
80
#define SERVER 263
81
#define SERVERS 264
82
#define SENSOR 265
83
#define CORRECTION 266
84
#define RTABLE 267
85
#define REFID 268
86
#define STRATUM 269
87
#define WEIGHT 270
88
#define ERROR 271
89
#define STRING 272
90
#define NUMBER 273
91
#define YYERRCODE 256
92
const short yylhs[] =
93
	{                                        -1,
94
    0,    0,    0,    0,   17,   17,   17,   17,   17,   17,
95
   17,    1,    2,   18,    3,    3,    4,    4,    5,   19,
96
    6,    6,    7,    7,    8,   20,    9,    9,   10,   10,
97
   11,   11,   11,   11,   12,   14,   15,   16,   13,
98
};
99
const short yylen[] =
100
	{                                         2,
101
    0,    2,    3,    3,    4,    3,    3,    3,    3,    3,
102
    3,    1,    1,    0,    2,    0,    2,    1,    1,    0,
103
    2,    0,    2,    1,    1,    0,    2,    0,    2,    1,
104
    1,    1,    1,    1,    2,    2,    2,    2,    2,
105
};
106
const short yydefred[] =
107
	{                                      1,
108
    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,
109
    0,    4,    0,    0,    0,    0,   12,    0,    0,    0,
110
    3,    0,   13,   10,    9,    6,    8,    0,    7,   11,
111
    0,    5,    0,    0,    0,   24,   25,    0,    0,    0,
112
    0,   30,   31,   32,   33,   34,    0,    0,   18,   19,
113
   38,   23,   35,   36,   37,   29,   39,   17,
114
};
115
const short yydgoto[] =
116
	{                                       1,
117
   18,   24,   32,   48,   49,   27,   35,   36,   30,   41,
118
   42,   43,   50,   44,   45,   37,   11,   33,   28,   31,
119
};
120
const short yysindex[] =
121
	{                                      0,
122
    7,   -7, -252, -254, -253, -251, -256, -256, -250,    0,
123
    8,    0, -256, -249, -249, -248,    0,    0,    0,    0,
124
    0,    0,    0,    0,    0,    0,    0, -245,    0,    0,
125
 -255,    0, -247, -246, -245,    0,    0, -244, -242, -241,
126
 -255,    0,    0,    0,    0,    0, -240, -247,    0,    0,
127
    0,    0,    0,    0,    0,    0,    0,    0,};
128
const short yyrindex[] =
129
	{                                      0,
130
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
131
    0,    0,    0,    0,    0,    0,    0,   -9,   -9,  -10,
132
    0,   -5,    0,    0,    0,    0,    0,    0,    0,    0,
133
    0,    0,    0,    0,    8,    0,    0,    0,    0,    0,
134
    9,    0,    0,    0,    0,    0,    0,   11,    0,    0,
135
    0,    0,    0,    0,    0,    0,    0,    0,};
136
const short yygindex[] =
137
	{                                      0,
138
   -4,   13,    0,    0,  -22,   12,    0,   -1,    0,    0,
139
   -6,    0,    0,    0,    0,  -29,    0,    0,    0,    0,
140
};
141
#define YYTABLESIZE 272
142
const short yytable[] =
143
	{                                      28,
144
   22,   46,   12,   19,   16,   13,   14,   15,   22,   16,
145
   38,   46,   39,   40,   34,   17,   10,   21,   27,   47,
146
   15,   20,   23,   26,   34,   58,   51,   25,   53,   54,
147
   29,   55,   57,   52,   56,    0,    0,    0,    0,    0,
148
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
149
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
150
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
151
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
152
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
153
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
154
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
155
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
156
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
157
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
158
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
159
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
160
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
161
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
162
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
163
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
164
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
165
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
166
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
167
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
168
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
169
    0,    0,    0,    0,    0,   26,    0,   26,   26,   26,
170
   20,   14,    2,    3,    0,    4,    5,    0,    6,    7,
171
    8,    9,
172
};
173
const short yycheck[] =
174
	{                                      10,
175
   10,   31,   10,    8,   10,  258,  261,  261,   13,  261,
176
  266,   41,  268,  269,  270,  272,   10,   10,   10,  267,
177
   10,  272,  272,  272,  270,   48,  273,   15,  273,  272,
178
   19,  273,  273,   35,   41,   -1,   -1,   -1,   -1,   -1,
179
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
180
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
181
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
182
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
183
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
184
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
185
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
186
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
187
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
188
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
189
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
190
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
191
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
192
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
193
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
194
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
195
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
196
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
197
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
198
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
199
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
200
   -1,   -1,   -1,   -1,   -1,  266,   -1,  268,  269,  270,
201
  270,  267,  256,  257,   -1,  259,  260,   -1,  262,  263,
202
  264,  265,
203
};
204
#define YYFINAL 1
205
#ifndef YYDEBUG
206
#define YYDEBUG 0
207
#endif
208
#define YYMAXTOKEN 273
209
#if YYDEBUG
210
const char * const yyname[] =
211
	{
212
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
213
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
214
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
215
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
216
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
217
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
218
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"LISTEN","ON","CONSTRAINT",
219
"CONSTRAINTS","FROM","QUERY","SERVER","SERVERS","SENSOR","CORRECTION","RTABLE",
220
"REFID","STRATUM","WEIGHT","ERROR","STRING","NUMBER",
221
};
222
const char * const yyrule[] =
223
	{"$accept : grammar",
224
"grammar :",
225
"grammar : grammar '\\n'",
226
"grammar : grammar main '\\n'",
227
"grammar : grammar error '\\n'",
228
"main : LISTEN ON address listen_opts",
229
"main : QUERY FROM STRING",
230
"main : SERVERS address server_opts",
231
"main : SERVER address server_opts",
232
"main : CONSTRAINTS FROM url",
233
"main : CONSTRAINT FROM url",
234
"main : SENSOR STRING sensor_opts",
235
"address : STRING",
236
"url : STRING",
237
"$$1 :",
238
"listen_opts : $$1 listen_opts_l",
239
"listen_opts :",
240
"listen_opts_l : listen_opts_l listen_opt",
241
"listen_opts_l : listen_opt",
242
"listen_opt : rtable",
243
"$$2 :",
244
"server_opts : $$2 server_opts_l",
245
"server_opts :",
246
"server_opts_l : server_opts_l server_opt",
247
"server_opts_l : server_opt",
248
"server_opt : weight",
249
"$$3 :",
250
"sensor_opts : $$3 sensor_opts_l",
251
"sensor_opts :",
252
"sensor_opts_l : sensor_opts_l sensor_opt",
253
"sensor_opts_l : sensor_opt",
254
"sensor_opt : correction",
255
"sensor_opt : refid",
256
"sensor_opt : stratum",
257
"sensor_opt : weight",
258
"correction : CORRECTION NUMBER",
259
"refid : REFID STRING",
260
"stratum : STRATUM NUMBER",
261
"weight : WEIGHT NUMBER",
262
"rtable : RTABLE NUMBER",
263
};
264
#endif
265
#ifdef YYSTACKSIZE
266
#undef YYMAXDEPTH
267
#define YYMAXDEPTH YYSTACKSIZE
268
#else
269
#ifdef YYMAXDEPTH
270
#define YYSTACKSIZE YYMAXDEPTH
271
#else
272
#define YYSTACKSIZE 10000
273
#define YYMAXDEPTH 10000
274
#endif
275
#endif
276
#define YYINITSTACKSIZE 200
277
/* LINTUSED */
278
int yydebug;
279
int yynerrs;
280
int yyerrflag;
281
int yychar;
282
short *yyssp;
283
YYSTYPE *yyvsp;
284
YYSTYPE yyval;
285
YYSTYPE yylval;
286
short *yyss;
287
short *yysslim;
288
YYSTYPE *yyvs;
289
unsigned int yystacksize;
290
int yyparse(void);
291
#line 447 "parse.y"
292
293
void
294
opts_default(void)
295
{
296
	memset(&opts, 0, sizeof opts);
297
	opts.weight = 1;
298
	opts.stratum = 1;
299
}
300
301
struct keywords {
302
	const char	*k_name;
303
	int		 k_val;
304
};
305
306
int
307
yyerror(const char *fmt, ...)
308
{
309
	va_list		 ap;
310
	char		*msg;
311
312
	file->errors++;
313
	va_start(ap, fmt);
314
	if (vasprintf(&msg, fmt, ap) == -1)
315
		fatalx("yyerror vasprintf");
316
	va_end(ap);
317
	log_warnx("%s:%d: %s", file->name, yylval.lineno, msg);
318
	free(msg);
319
	return (0);
320
}
321
322
int
323
kw_cmp(const void *k, const void *e)
324
{
325
	return (strcmp(k, ((const struct keywords *)e)->k_name));
326
}
327
328
int
329
lookup(char *s)
330
{
331
	/* this has to be sorted always */
332
	static const struct keywords keywords[] = {
333
		{ "constraint",		CONSTRAINT},
334
		{ "constraints",	CONSTRAINTS},
335
		{ "correction",		CORRECTION},
336
		{ "from",		FROM},
337
		{ "listen",		LISTEN},
338
		{ "on",			ON},
339
		{ "query",		QUERY},
340
		{ "refid",		REFID},
341
		{ "rtable",		RTABLE},
342
		{ "sensor",		SENSOR},
343
		{ "server",		SERVER},
344
		{ "servers",		SERVERS},
345
		{ "stratum",		STRATUM},
346
		{ "weight",		WEIGHT}
347
	};
348
	const struct keywords	*p;
349
350
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
351
	    sizeof(keywords[0]), kw_cmp);
352
353
	if (p)
354
		return (p->k_val);
355
	else
356
		return (STRING);
357
}
358
359
#define MAXPUSHBACK	128
360
361
u_char	*parsebuf;
362
int	 parseindex;
363
u_char	 pushback_buffer[MAXPUSHBACK];
364
int	 pushback_index = 0;
365
366
int
367
lgetc(int quotec)
368
{
369
	int		c, next;
370
371
	if (parsebuf) {
372
		/* Read character from the parsebuffer instead of input. */
373
		if (parseindex >= 0) {
374
			c = parsebuf[parseindex++];
375
			if (c != '\0')
376
				return (c);
377
			parsebuf = NULL;
378
		} else
379
			parseindex++;
380
	}
381
382
	if (pushback_index)
383
		return (pushback_buffer[--pushback_index]);
384
385
	if (quotec) {
386
		if ((c = getc(file->stream)) == EOF) {
387
			yyerror("reached end of file while parsing "
388
			    "quoted string");
389
			if (file == topfile || popfile() == EOF)
390
				return (EOF);
391
			return (quotec);
392
		}
393
		return (c);
394
	}
395
396
	while ((c = getc(file->stream)) == '\\') {
397
		next = getc(file->stream);
398
		if (next != '\n') {
399
			c = next;
400
			break;
401
		}
402
		yylval.lineno = file->lineno;
403
		file->lineno++;
404
	}
405
406
	while (c == EOF) {
407
		if (file == topfile || popfile() == EOF)
408
			return (EOF);
409
		c = getc(file->stream);
410
	}
411
	return (c);
412
}
413
414
int
415
lungetc(int c)
416
{
417
	if (c == EOF)
418
		return (EOF);
419
	if (parsebuf) {
420
		parseindex--;
421
		if (parseindex >= 0)
422
			return (c);
423
	}
424
	if (pushback_index < MAXPUSHBACK-1)
425
		return (pushback_buffer[pushback_index++] = c);
426
	else
427
		return (EOF);
428
}
429
430
int
431
findeol(void)
432
{
433
	int	c;
434
435
	parsebuf = NULL;
436
437
	/* skip to either EOF or the first real EOL */
438
	while (1) {
439
		if (pushback_index)
440
			c = pushback_buffer[--pushback_index];
441
		else
442
			c = lgetc(0);
443
		if (c == '\n') {
444
			file->lineno++;
445
			break;
446
		}
447
		if (c == EOF)
448
			break;
449
	}
450
	return (ERROR);
451
}
452
453
int
454
yylex(void)
455
{
456
	u_char	 buf[8096];
457
	u_char	*p;
458
	int	 quotec, next, c;
459
	int	 token;
460
461
	p = buf;
462
	while ((c = lgetc(0)) == ' ' || c == '\t')
463
		; /* nothing */
464
465
	yylval.lineno = file->lineno;
466
	if (c == '#')
467
		while ((c = lgetc(0)) != '\n' && c != EOF)
468
			; /* nothing */
469
470
	switch (c) {
471
	case '\'':
472
	case '"':
473
		quotec = c;
474
		while (1) {
475
			if ((c = lgetc(quotec)) == EOF)
476
				return (0);
477
			if (c == '\n') {
478
				file->lineno++;
479
				continue;
480
			} else if (c == '\\') {
481
				if ((next = lgetc(quotec)) == EOF)
482
					return (0);
483
				if (next == quotec || c == ' ' || c == '\t')
484
					c = next;
485
				else if (next == '\n') {
486
					file->lineno++;
487
					continue;
488
				} else
489
					lungetc(next);
490
			} else if (c == quotec) {
491
				*p = '\0';
492
				break;
493
			} else if (c == '\0') {
494
				yyerror("syntax error");
495
				return (findeol());
496
			}
497
			if (p + 1 >= buf + sizeof(buf) - 1) {
498
				yyerror("string too long");
499
				return (findeol());
500
			}
501
			*p++ = c;
502
		}
503
		yylval.v.string = strdup(buf);
504
		if (yylval.v.string == NULL)
505
			fatal("yylex: strdup");
506
		return (STRING);
507
	}
508
509
#define allowed_to_end_number(x) \
510
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
511
512
	if (c == '-' || isdigit(c)) {
513
		do {
514
			*p++ = c;
515
			if ((unsigned)(p-buf) >= sizeof(buf)) {
516
				yyerror("string too long");
517
				return (findeol());
518
			}
519
		} while ((c = lgetc(0)) != EOF && isdigit(c));
520
		lungetc(c);
521
		if (p == buf + 1 && buf[0] == '-')
522
			goto nodigits;
523
		if (c == EOF || allowed_to_end_number(c)) {
524
			const char *errstr = NULL;
525
526
			*p = '\0';
527
			yylval.v.number = strtonum(buf, LLONG_MIN,
528
			    LLONG_MAX, &errstr);
529
			if (errstr) {
530
				yyerror("\"%s\" invalid number: %s",
531
				    buf, errstr);
532
				return (findeol());
533
			}
534
			return (NUMBER);
535
		} else {
536
nodigits:
537
			while (p > buf + 1)
538
				lungetc(*--p);
539
			c = *--p;
540
			if (c == '-')
541
				return (c);
542
		}
543
	}
544
545
#define allowed_in_string(x) \
546
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
547
	x != '{' && x != '}' && x != '<' && x != '>' && \
548
	x != '!' && x != '=' && x != '/' && x != '#' && \
549
	x != ','))
550
551
	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
552
		do {
553
			*p++ = c;
554
			if ((unsigned)(p-buf) >= sizeof(buf)) {
555
				yyerror("string too long");
556
				return (findeol());
557
			}
558
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
559
		lungetc(c);
560
		*p = '\0';
561
		if ((token = lookup(buf)) == STRING)
562
			if ((yylval.v.string = strdup(buf)) == NULL)
563
				fatal("yylex: strdup");
564
		return (token);
565
	}
566
	if (c == '\n') {
567
		yylval.lineno = file->lineno;
568
		file->lineno++;
569
	}
570
	if (c == EOF)
571
		return (0);
572
	return (c);
573
}
574
575
struct file *
576
pushfile(const char *name)
577
{
578
	struct file	*nfile;
579
580
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
581
		log_warn("malloc");
582
		return (NULL);
583
	}
584
	if ((nfile->name = strdup(name)) == NULL) {
585
		log_warn("malloc");
586
		free(nfile);
587
		return (NULL);
588
	}
589
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
590
		log_warn("%s", nfile->name);
591
		free(nfile->name);
592
		free(nfile);
593
		return (NULL);
594
	}
595
	nfile->lineno = 1;
596
	TAILQ_INSERT_TAIL(&files, nfile, entry);
597
	return (nfile);
598
}
599
600
int
601
popfile(void)
602
{
603
	struct file	*prev;
604
605
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
606
		prev->errors += file->errors;
607
608
	TAILQ_REMOVE(&files, file, entry);
609
	fclose(file->stream);
610
	free(file->name);
611
	free(file);
612
	file = prev;
613
	return (file ? 0 : EOF);
614
}
615
616
int
617
parse_config(const char *filename, struct ntpd_conf *xconf)
618
{
619
	int		 errors = 0;
620
621
	conf = xconf;
622
	TAILQ_INIT(&conf->listen_addrs);
623
	TAILQ_INIT(&conf->ntp_peers);
624
	TAILQ_INIT(&conf->ntp_conf_sensors);
625
	TAILQ_INIT(&conf->constraints);
626
627
	if ((file = pushfile(filename)) == NULL) {
628
		return (-1);
629
	}
630
	topfile = file;
631
632
	yyparse();
633
	errors = file->errors;
634
	popfile();
635
636
	return (errors ? -1 : 0);
637
}
638
#line 631 "parse.c"
639
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
640
static int yygrowstack(void)
641
{
642
    unsigned int newsize;
643
    long sslen;
644
    short *newss;
645
    YYSTYPE *newvs;
646
647
    if ((newsize = yystacksize) == 0)
648
        newsize = YYINITSTACKSIZE;
649
    else if (newsize >= YYMAXDEPTH)
650
        return -1;
651
    else if ((newsize *= 2) > YYMAXDEPTH)
652
        newsize = YYMAXDEPTH;
653
    sslen = yyssp - yyss;
654
#ifdef SIZE_MAX
655
#define YY_SIZE_MAX SIZE_MAX
656
#else
657
#define YY_SIZE_MAX 0xffffffffU
658
#endif
659
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
660
        goto bail;
661
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
662
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
663
    if (newss == NULL)
664
        goto bail;
665
    yyss = newss;
666
    yyssp = newss + sslen;
667
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
668
        goto bail;
669
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
670
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
671
    if (newvs == NULL)
672
        goto bail;
673
    yyvs = newvs;
674
    yyvsp = newvs + sslen;
675
    yystacksize = newsize;
676
    yysslim = yyss + newsize - 1;
677
    return 0;
678
bail:
679
    if (yyss)
680
            free(yyss);
681
    if (yyvs)
682
            free(yyvs);
683
    yyss = yyssp = NULL;
684
    yyvs = yyvsp = NULL;
685
    yystacksize = 0;
686
    return -1;
687
}
688
689
#define YYABORT goto yyabort
690
#define YYREJECT goto yyabort
691
#define YYACCEPT goto yyaccept
692
#define YYERROR goto yyerrlab
693
int
694
yyparse(void)
695
{
696
    int yym, yyn, yystate;
697
#if YYDEBUG
698
    const char *yys;
699
700
    if ((yys = getenv("YYDEBUG")))
701
    {
702
        yyn = *yys;
703
        if (yyn >= '0' && yyn <= '9')
704
            yydebug = yyn - '0';
705
    }
706
#endif /* YYDEBUG */
707
708
    yynerrs = 0;
709
    yyerrflag = 0;
710
    yychar = (-1);
711
712
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
713
    yyssp = yyss;
714
    yyvsp = yyvs;
715
    *yyssp = yystate = 0;
716
717
yyloop:
718
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
719
    if (yychar < 0)
720
    {
721
        if ((yychar = yylex()) < 0) yychar = 0;
722
#if YYDEBUG
723
        if (yydebug)
724
        {
725
            yys = 0;
726
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
727
            if (!yys) yys = "illegal-symbol";
728
            printf("%sdebug: state %d, reading %d (%s)\n",
729
                    YYPREFIX, yystate, yychar, yys);
730
        }
731
#endif
732
    }
733
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
734
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
735
    {
736
#if YYDEBUG
737
        if (yydebug)
738
            printf("%sdebug: state %d, shifting to state %d\n",
739
                    YYPREFIX, yystate, yytable[yyn]);
740
#endif
741
        if (yyssp >= yysslim && yygrowstack())
742
        {
743
            goto yyoverflow;
744
        }
745
        *++yyssp = yystate = yytable[yyn];
746
        *++yyvsp = yylval;
747
        yychar = (-1);
748
        if (yyerrflag > 0)  --yyerrflag;
749
        goto yyloop;
750
    }
751
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
752
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
753
    {
754
        yyn = yytable[yyn];
755
        goto yyreduce;
756
    }
757
    if (yyerrflag) goto yyinrecovery;
758
#if defined(__GNUC__)
759
    goto yynewerror;
760
#endif
761
yynewerror:
762
    yyerror("syntax error");
763
#if defined(__GNUC__)
764
    goto yyerrlab;
765
#endif
766
yyerrlab:
767
    ++yynerrs;
768
yyinrecovery:
769
    if (yyerrflag < 3)
770
    {
771
        yyerrflag = 3;
772
        for (;;)
773
        {
774
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
775
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
776
            {
777
#if YYDEBUG
778
                if (yydebug)
779
                    printf("%sdebug: state %d, error recovery shifting\
780
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
781
#endif
782
                if (yyssp >= yysslim && yygrowstack())
783
                {
784
                    goto yyoverflow;
785
                }
786
                *++yyssp = yystate = yytable[yyn];
787
                *++yyvsp = yylval;
788
                goto yyloop;
789
            }
790
            else
791
            {
792
#if YYDEBUG
793
                if (yydebug)
794
                    printf("%sdebug: error recovery discarding state %d\n",
795
                            YYPREFIX, *yyssp);
796
#endif
797
                if (yyssp <= yyss) goto yyabort;
798
                --yyssp;
799
                --yyvsp;
800
            }
801
        }
802
    }
803
    else
804
    {
805
        if (yychar == 0) goto yyabort;
806
#if YYDEBUG
807
        if (yydebug)
808
        {
809
            yys = 0;
810
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
811
            if (!yys) yys = "illegal-symbol";
812
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
813
                    YYPREFIX, yystate, yychar, yys);
814
        }
815
#endif
816
        yychar = (-1);
817
        goto yyloop;
818
    }
819
yyreduce:
820
#if YYDEBUG
821
    if (yydebug)
822
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
823
                YYPREFIX, yystate, yyn, yyrule[yyn]);
824
#endif
825
    yym = yylen[yyn];
826
    if (yym)
827
        yyval = yyvsp[1-yym];
828
    else
829
        memset(&yyval, 0, sizeof yyval);
830
    switch (yyn)
831
    {
832
case 4:
833
#line 104 "parse.y"
834
{ file->errors++; }
835
break;
836
case 5:
837
#line 107 "parse.y"
838
{
839
			struct listen_addr	*la;
840
			struct ntp_addr		*h, *next;
841
842
			if ((h = yyvsp[-1].v.addr->a) == NULL &&
843
			    (host_dns(yyvsp[-1].v.addr->name, &h) == -1 || !h)) {
844
				yyerror("could not resolve \"%s\"", yyvsp[-1].v.addr->name);
845
				free(yyvsp[-1].v.addr->name);
846
				free(yyvsp[-1].v.addr);
847
				YYERROR;
848
			}
849
850
			for (; h != NULL; h = next) {
851
				next = h->next;
852
				la = calloc(1, sizeof(struct listen_addr));
853
				if (la == NULL)
854
					fatal("listen on calloc");
855
				la->fd = -1;
856
				la->rtable = yyvsp[0].v.opts.rtable;
857
				memcpy(&la->sa, &h->ss,
858
				    sizeof(struct sockaddr_storage));
859
				TAILQ_INSERT_TAIL(&conf->listen_addrs, la,
860
				    entry);
861
				free(h);
862
			}
863
			free(yyvsp[-1].v.addr->name);
864
			free(yyvsp[-1].v.addr);
865
		}
866
break;
867
case 6:
868
#line 135 "parse.y"
869
{
870
			struct sockaddr_in sin4;
871
			struct sockaddr_in6 sin6;
872
873
			memset(&sin4, 0, sizeof(sin4));
874
			sin4.sin_family = AF_INET;
875
			sin4.sin_len = sizeof(struct sockaddr_in);
876
			memset(&sin6, 0, sizeof(sin6));
877
			sin6.sin6_family = AF_INET6;
878
			sin6.sin6_len = sizeof(struct sockaddr_in6);
879
880
			if (inet_pton(AF_INET, yyvsp[0].v.string, &sin4.sin_addr) == 1)
881
				memcpy(&query_addr4, &sin4, sin4.sin_len);
882
			else if (inet_pton(AF_INET6, yyvsp[0].v.string, &sin6.sin6_addr) == 1)
883
				memcpy(&query_addr6, &sin6, sin6.sin6_len);
884
			else {
885
				yyerror("invalid IPv4 or IPv6 address: %s\n",
886
				    yyvsp[0].v.string);
887
				free(yyvsp[0].v.string);
888
				YYERROR;
889
			}
890
891
			free(yyvsp[0].v.string);
892
		}
893
break;
894
case 7:
895
#line 159 "parse.y"
896
{
897
			struct ntp_peer		*p;
898
			struct ntp_addr		*h, *next;
899
900
			h = yyvsp[-1].v.addr->a;
901
			do {
902
				if (h != NULL) {
903
					next = h->next;
904
					if (h->ss.ss_family != AF_INET &&
905
					    h->ss.ss_family != AF_INET6) {
906
						yyerror("IPv4 or IPv6 address "
907
						    "or hostname expected");
908
						free(h);
909
						free(yyvsp[-1].v.addr->name);
910
						free(yyvsp[-1].v.addr);
911
						YYERROR;
912
					}
913
					h->next = NULL;
914
				} else
915
					next = NULL;
916
917
				p = new_peer();
918
				p->weight = yyvsp[0].v.opts.weight;
919
				p->query_addr4 = query_addr4;
920
				p->query_addr6 = query_addr6;
921
				p->addr = h;
922
				p->addr_head.a = h;
923
				p->addr_head.pool = 1;
924
				p->addr_head.name = strdup(yyvsp[-1].v.addr->name);
925
				if (p->addr_head.name == NULL)
926
					fatal(NULL);
927
				if (p->addr != NULL)
928
					p->state = STATE_DNS_DONE;
929
				TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry);
930
				h = next;
931
			} while (h != NULL);
932
933
			free(yyvsp[-1].v.addr->name);
934
			free(yyvsp[-1].v.addr);
935
		}
936
break;
937
case 8:
938
#line 199 "parse.y"
939
{
940
			struct ntp_peer		*p;
941
			struct ntp_addr		*h, *next;
942
943
			p = new_peer();
944
			for (h = yyvsp[-1].v.addr->a; h != NULL; h = next) {
945
				next = h->next;
946
				if (h->ss.ss_family != AF_INET &&
947
				    h->ss.ss_family != AF_INET6) {
948
					yyerror("IPv4 or IPv6 address "
949
					    "or hostname expected");
950
					free(h);
951
					free(p);
952
					free(yyvsp[-1].v.addr->name);
953
					free(yyvsp[-1].v.addr);
954
					YYERROR;
955
				}
956
				h->next = p->addr;
957
				p->addr = h;
958
			}
959
960
			p->weight = yyvsp[0].v.opts.weight;
961
			p->query_addr4 = query_addr4;
962
			p->query_addr6 = query_addr6;
963
			p->addr_head.a = p->addr;
964
			p->addr_head.pool = 0;
965
			p->addr_head.name = strdup(yyvsp[-1].v.addr->name);
966
			if (p->addr_head.name == NULL)
967
				fatal(NULL);
968
			if (p->addr != NULL)
969
				p->state = STATE_DNS_DONE;
970
			TAILQ_INSERT_TAIL(&conf->ntp_peers, p, entry);
971
			free(yyvsp[-1].v.addr->name);
972
			free(yyvsp[-1].v.addr);
973
		}
974
break;
975
case 9:
976
#line 234 "parse.y"
977
{
978
			struct constraint	*p;
979
			struct ntp_addr		*h, *next;
980
981
			h = yyvsp[0].v.addr->a;
982
			do {
983
				if (h != NULL) {
984
					next = h->next;
985
					if (h->ss.ss_family != AF_INET &&
986
					    h->ss.ss_family != AF_INET6) {
987
						yyerror("IPv4 or IPv6 address "
988
						    "or hostname expected");
989
						free(h);
990
						free(yyvsp[0].v.addr->name);
991
						free(yyvsp[0].v.addr->path);
992
						free(yyvsp[0].v.addr);
993
						YYERROR;
994
					}
995
					h->next = NULL;
996
				} else
997
					next = NULL;
998
999
				p = new_constraint();
1000
				p->addr = h;
1001
				p->addr_head.a = h;
1002
				p->addr_head.pool = 1;
1003
				p->addr_head.name = strdup(yyvsp[0].v.addr->name);
1004
				p->addr_head.path = strdup(yyvsp[0].v.addr->path);
1005
				if (p->addr_head.name == NULL ||
1006
				    p->addr_head.path == NULL)
1007
					fatal(NULL);
1008
				if (p->addr != NULL)
1009
					p->state = STATE_DNS_DONE;
1010
				constraint_add(p);
1011
				h = next;
1012
			} while (h != NULL);
1013
1014
			free(yyvsp[0].v.addr->name);
1015
			free(yyvsp[0].v.addr);
1016
		}
1017
break;
1018
case 10:
1019
#line 274 "parse.y"
1020
{
1021
			struct constraint	*p;
1022
			struct ntp_addr		*h, *next;
1023
1024
			p = new_constraint();
1025
			for (h = yyvsp[0].v.addr->a; h != NULL; h = next) {
1026
				next = h->next;
1027
				if (h->ss.ss_family != AF_INET &&
1028
				    h->ss.ss_family != AF_INET6) {
1029
					yyerror("IPv4 or IPv6 address "
1030
					    "or hostname expected");
1031
					free(h);
1032
					free(p);
1033
					free(yyvsp[0].v.addr->name);
1034
					free(yyvsp[0].v.addr->path);
1035
					free(yyvsp[0].v.addr);
1036
					YYERROR;
1037
				}
1038
				h->next = p->addr;
1039
				p->addr = h;
1040
			}
1041
1042
			p->addr_head.a = p->addr;
1043
			p->addr_head.pool = 0;
1044
			p->addr_head.name = strdup(yyvsp[0].v.addr->name);
1045
			p->addr_head.path = strdup(yyvsp[0].v.addr->path);
1046
			if (p->addr_head.name == NULL ||
1047
			    p->addr_head.path == NULL)
1048
				fatal(NULL);
1049
			if (p->addr != NULL)
1050
				p->state = STATE_DNS_DONE;
1051
			constraint_add(p);
1052
			free(yyvsp[0].v.addr->name);
1053
			free(yyvsp[0].v.addr);
1054
		}
1055
break;
1056
case 11:
1057
#line 309 "parse.y"
1058
{
1059
			struct ntp_conf_sensor	*s;
1060
1061
			s = new_sensor(yyvsp[-1].v.string);
1062
			s->weight = yyvsp[0].v.opts.weight;
1063
			s->correction = yyvsp[0].v.opts.correction;
1064
			s->refstr = yyvsp[0].v.opts.refstr;
1065
			s->stratum = yyvsp[0].v.opts.stratum;
1066
			free(yyvsp[-1].v.string);
1067
			TAILQ_INSERT_TAIL(&conf->ntp_conf_sensors, s, entry);
1068
		}
1069
break;
1070
case 12:
1071
#line 322 "parse.y"
1072
{
1073
			if ((yyval.v.addr = calloc(1, sizeof(struct ntp_addr_wrap))) ==
1074
			    NULL)
1075
				fatal(NULL);
1076
			host(yyvsp[0].v.string, &yyval.v.addr->a);
1077
			yyval.v.addr->name = yyvsp[0].v.string;
1078
		}
1079
break;
1080
case 13:
1081
#line 331 "parse.y"
1082
{
1083
			char	*hname, *path;
1084
1085
			if ((yyval.v.addr = calloc(1, sizeof(struct ntp_addr_wrap))) ==
1086
			    NULL)
1087
				fatal("calloc");
1088
1089
			if (strncmp("https://", yyvsp[0].v.string,
1090
			    strlen("https://")) != 0) {
1091
				host(yyvsp[0].v.string, &yyval.v.addr->a);
1092
				yyval.v.addr->name = yyvsp[0].v.string;
1093
			} else {
1094
				hname = yyvsp[0].v.string + strlen("https://");
1095
1096
				path = hname + strcspn(hname, "/\\");
1097
				if (*path != '\0') {
1098
					if ((yyval.v.addr->path = strdup(path)) == NULL)
1099
						fatal("strdup");
1100
					*path = '\0';
1101
				}
1102
				host(hname, &yyval.v.addr->a);
1103
				if ((yyval.v.addr->name = strdup(hname)) == NULL)
1104
					fatal("strdup");
1105
			}
1106
			if (yyval.v.addr->path == NULL &&
1107
			    (yyval.v.addr->path = strdup("/")) == NULL)
1108
				fatal("strdup");
1109
		}
1110
break;
1111
case 14:
1112
#line 361 "parse.y"
1113
{ opts_default(); }
1114
break;
1115
case 15:
1116
#line 363 "parse.y"
1117
{ yyval.v.opts = opts; }
1118
break;
1119
case 16:
1120
#line 364 "parse.y"
1121
{ opts_default(); yyval.v.opts = opts; }
1122
break;
1123
case 20:
1124
#line 372 "parse.y"
1125
{ opts_default(); }
1126
break;
1127
case 21:
1128
#line 374 "parse.y"
1129
{ yyval.v.opts = opts; }
1130
break;
1131
case 22:
1132
#line 375 "parse.y"
1133
{ opts_default(); yyval.v.opts = opts; }
1134
break;
1135
case 26:
1136
#line 383 "parse.y"
1137
{ opts_default(); }
1138
break;
1139
case 27:
1140
#line 385 "parse.y"
1141
{ yyval.v.opts = opts; }
1142
break;
1143
case 28:
1144
#line 386 "parse.y"
1145
{ opts_default(); yyval.v.opts = opts; }
1146
break;
1147
case 35:
1148
#line 397 "parse.y"
1149
{
1150
			if (yyvsp[0].v.number < -127000000 || yyvsp[0].v.number > 127000000) {
1151
				yyerror("correction must be between "
1152
				    "-127000000 and 127000000 microseconds");
1153
				YYERROR;
1154
			}
1155
			opts.correction = yyvsp[0].v.number;
1156
		}
1157
break;
1158
case 36:
1159
#line 407 "parse.y"
1160
{
1161
			size_t l = strlen(yyvsp[0].v.string);
1162
1163
			if (l < 1 || l > 4) {
1164
				yyerror("refid must be 1 to 4 characters");
1165
				free(yyvsp[0].v.string);
1166
				YYERROR;
1167
			}
1168
			opts.refstr = yyvsp[0].v.string;
1169
		}
1170
break;
1171
case 37:
1172
#line 419 "parse.y"
1173
{
1174
			if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > 15) {
1175
				yyerror("stratum must be between "
1176
				    "1 and 15");
1177
				YYERROR;
1178
			}
1179
			opts.stratum = yyvsp[0].v.number;
1180
		}
1181
break;
1182
case 38:
1183
#line 429 "parse.y"
1184
{
1185
			if (yyvsp[0].v.number < 1 || yyvsp[0].v.number > 10) {
1186
				yyerror("weight must be between 1 and 10");
1187
				YYERROR;
1188
			}
1189
			opts.weight = yyvsp[0].v.number;
1190
		}
1191
break;
1192
case 39:
1193
#line 436 "parse.y"
1194
{
1195
			if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RT_TABLEID_MAX) {
1196
				yyerror("rtable must be between 1"
1197
				    " and RT_TABLEID_MAX");
1198
				YYERROR;
1199
			}
1200
			opts.rtable = yyvsp[0].v.number;
1201
		}
1202
break;
1203
#line 1196 "parse.c"
1204
    }
1205
    yyssp -= yym;
1206
    yystate = *yyssp;
1207
    yyvsp -= yym;
1208
    yym = yylhs[yyn];
1209
    if (yystate == 0 && yym == 0)
1210
    {
1211
#if YYDEBUG
1212
        if (yydebug)
1213
            printf("%sdebug: after reduction, shifting from state 0 to\
1214
 state %d\n", YYPREFIX, YYFINAL);
1215
#endif
1216
        yystate = YYFINAL;
1217
        *++yyssp = YYFINAL;
1218
        *++yyvsp = yyval;
1219
        if (yychar < 0)
1220
        {
1221
            if ((yychar = yylex()) < 0) yychar = 0;
1222
#if YYDEBUG
1223
            if (yydebug)
1224
            {
1225
                yys = 0;
1226
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1227
                if (!yys) yys = "illegal-symbol";
1228
                printf("%sdebug: state %d, reading %d (%s)\n",
1229
                        YYPREFIX, YYFINAL, yychar, yys);
1230
            }
1231
#endif
1232
        }
1233
        if (yychar == 0) goto yyaccept;
1234
        goto yyloop;
1235
    }
1236
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1237
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1238
        yystate = yytable[yyn];
1239
    else
1240
        yystate = yydgoto[yym];
1241
#if YYDEBUG
1242
    if (yydebug)
1243
        printf("%sdebug: after reduction, shifting from state %d \
1244
to state %d\n", YYPREFIX, *yyssp, yystate);
1245
#endif
1246
    if (yyssp >= yysslim && yygrowstack())
1247
    {
1248
        goto yyoverflow;
1249
    }
1250
    *++yyssp = yystate;
1251
    *++yyvsp = yyval;
1252
    goto yyloop;
1253
yyoverflow:
1254
    yyerror("yacc stack overflow");
1255
yyabort:
1256
    if (yyss)
1257
            free(yyss);
1258
    if (yyvs)
1259
            free(yyvs);
1260
    yyss = yyssp = NULL;
1261
    yyvs = yyvsp = NULL;
1262
    yystacksize = 0;
1263
    return (1);
1264
yyaccept:
1265
    if (yyss)
1266
            free(yyss);
1267
    if (yyvs)
1268
            free(yyvs);
1269
    yyss = yyssp = NULL;
1270
    yyvs = yyvsp = NULL;
1271
    yystacksize = 0;
1272
    return (0);
1273
}