#include <stdlib.h>
#include <string.h>
#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
#define YYLEX yylex()
#define YYEMPTY -1
#define yyclearin (yychar=(YYEMPTY))
#define yyerrok (yyerrflag=0)
#define YYRECOVERING() (yyerrflag!=0)
#define YYPREFIX "yy"
#line 2 "parse.y"

/*
 * Copyright (c) 2021-2024 Omar Polo <op@omarpolo.com>
 * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
 * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
 * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
 * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
 * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "gmid.h"

#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>

#include "log.h"

struct conf *conf;

static const char	*default_host = NULL;
static uint16_t		 default_port = 1965;

TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
static struct file {
	TAILQ_ENTRY(file)	 entry;
	FILE			*stream;
	char			*name;
	size_t			 ungetpos;
	size_t			 ungetsize;
	u_char			*ungetbuf;
	int			 eof_reached;
	int			 lineno;
	int			 errors;
} *file, *topfile;

struct file	*pushfile(const char *, int);
int		 popfile(void);
int		 yyparse(void);
int		 yylex(void);
void		 yyerror(const char *, ...)
    __attribute__((__format__ (printf, 1, 2)))
    __attribute__((__nonnull__ (1)));
void		 yywarn(const char *, ...)
    __attribute__((__format__ (printf, 1, 2)))
    __attribute__((__nonnull__ (1)));
int		 kw_cmp(const void *, const void *);
int		 lookup(char *);
int		 igetc(void);
int		 lgetc(int);
void		 lungetc(int);
int		 findeol(void);

/*
 * #define YYDEBUG 1
 * int yydebug = 1;
 */

TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
	TAILQ_ENTRY(sym)	 entry;
	int			 used;
	int			 persist;
	char			*name;
	char			*val;
};

int	 symset(const char *, const char *, int);
char	*symget(const char *);

char		*ensure_absolute_path(char*);
int		 check_block_code(int);
char		*check_block_fmt(char*);
int		 check_strip_no(int);
int		 check_prefork_num(int);
void		 advance_loc(void);
void		 advance_proxy(void);
int		 fastcgi_conf(const char *, const char *);
void		 add_param(char *, char *);
int		 getservice(const char *);
void		 listen_on(const char *, const char *, int);

static struct vhost		*host;
static struct location		*loc;
static struct proxy		*proxy;
static char			*current_media;
static int			 errors;

typedef struct {
	union {
		char	*string;
		int	 number;
	} v;
	int lineno;
} YYSTYPE;

#define YYSTYPE YYSTYPE

#line 131 "y.tab.c"
#define ACCESS 257
#define ALIAS 258
#define AUTO 259
#define BLOCK 260
#define CA 261
#define CERT 262
#define CGI 263
#define CHROOT 264
#define CLIENT 265
#define DEFAULT 266
#define FACILITY 267
#define FASTCGI 268
#define FOR_HOST 269
#define INCLUDE 270
#define INDEX 271
#define IPV6 272
#define KEY 273
#define LANG 274
#define LISTEN 275
#define LOCATION 276
#define LOG 277
#define OCSP 278
#define OFF 279
#define ON 280
#define PARAM 281
#define PORT 282
#define PREFORK 283
#define PROTO 284
#define PROTOCOLS 285
#define PROXY 286
#define PROXYV1 287
#define RELAY_TO 288
#define REQUIRE 289
#define RETURN 290
#define ROOT 291
#define SERVER 292
#define SNI 293
#define SOCKET 294
#define STRIP 295
#define STYLE 296
#define SYSLOG 297
#define TCP 298
#define TOEXT 299
#define TYPE 300
#define TYPES 301
#define USE_TLS 302
#define USER 303
#define VERIFYNAME 304
#define ERROR 305
#define STRING 306
#define NUM 307
#define YYERRCODE 256
const short yylhs[] =
	{                                        -1,
    0,    0,    7,    7,    7,    7,    7,    7,    7,    8,
    1,    1,    3,    3,    4,    4,    9,   10,   10,   10,
   10,   10,   10,   10,   13,   13,   15,   15,   16,   16,
   16,   16,   16,   17,   11,   11,   18,   18,   18,   18,
    5,    5,   19,   19,   19,   19,   19,   19,   19,   19,
   19,   19,   19,   19,   19,   24,   21,   23,   23,    2,
    2,    2,   26,   26,   25,   25,   27,   27,   27,   27,
   27,   27,   27,   27,   27,   28,   20,   20,   29,   29,
   22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
   22,   22,   30,   30,   30,   30,   31,   31,   32,   32,
   32,   32,   32,   32,   12,   33,   33,   36,   34,   34,
   35,   35,   37,    6,    6,   14,   14,
};
const short yylen[] =
	{                                         2,
    2,    1,    0,    3,    3,    3,    3,    3,    3,    2,
    1,    1,    2,    1,    1,    1,    3,    2,    2,    1,
    2,    2,    2,    2,    5,    2,    0,    3,    2,    2,
    3,    2,    1,    0,    7,    2,    0,    3,    3,    3,
    1,    1,    2,    2,    2,    2,    2,    4,    3,    5,
    5,    4,    6,    6,    1,    0,    7,    0,    2,    0,
    2,    2,    2,    3,    0,    3,    2,    2,    2,    1,
    3,    4,    2,    2,    2,    0,    7,    2,    0,    3,
    3,    4,    3,    1,    3,    1,    2,    2,    2,    4,
    2,    2,    5,    2,    2,    2,    0,    3,    4,    2,
    5,    3,    5,    2,    5,    3,    2,    0,    3,    1,
    2,    1,    1,    2,    2,    1,    0,
};
const short yydefred[] =
	{                                      0,
    0,    0,    0,    3,    0,  116,  114,  115,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,   20,   36,    9,   14,
    0,   10,   12,   11,   19,    0,    0,    0,    0,   26,
   21,   22,    0,    0,    0,    0,    0,    4,    5,    6,
    7,    8,   13,    0,    0,    0,   32,   27,    0,    0,
    0,    0,    0,    0,  108,  110,    0,    0,   25,    0,
   37,    0,  105,    0,  107,   28,    0,   16,   15,  113,
    0,  112,  106,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,   76,    0,    0,    0,   56,
    0,    0,    0,   35,    0,    0,    0,   55,   86,  111,
   78,    0,    0,    0,    0,    0,    0,   95,    0,    0,
    0,    0,    0,   94,    0,    0,    0,    0,    0,   89,
    0,    0,   58,    0,    0,   92,   38,   39,   40,   81,
    0,    0,    0,    0,    0,  104,   97,   42,   41,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,   52,
    0,    0,    0,    0,    0,   59,    0,    0,    0,   93,
    0,    0,    0,   79,    0,    0,   65,  101,    0,   98,
   53,   54,    0,    0,   64,    0,   77,    0,   61,   62,
    0,    0,    0,   70,    0,    0,    0,    0,    0,   57,
    0,   80,    0,    0,    0,    0,    0,    0,   74,   75,
   66,   71,    0,    0,
};
const short yydgoto[] =
	{                                       3,
   35,  185,   31,   80,  150,    6,    5,   22,   23,   24,
   25,   26,   27,    7,   63,   40,   59,   77,  105,  106,
  107,  108,  153,  133,  186,  166,  201,  129,  183,  109,
  158,  124,   67,   68,   81,   72,   82,
};
const short yysindex[] =
	{                                     -1,
   -1,   -1,    0,    0, 1351,    0,    0,    0, 1351,   -5,
 -266, -247, -237, -117, -239, -234, -266, -266,  -48, -266,
   16,   -1,   -1,   -1,   -1,   -1,    0,    0,    0,    0,
 -225,    0,    0,    0,    0, -266, -266, -238,   -1,    0,
    0,    0, -225, -225,   -1, -225, -266,    0,    0,    0,
    0,    0,    0, -225, -225, -266,    0,    0,  -38, -249,
 -225, -225, -115,   -1,    0,    0, -118,   -1,    0,   -1,
    0, -251,    0,   -1,    0,    0, 1411,    0,    0,    0,
 -251,    0,    0,  -39, -266, -182, -200, -266, -266, -209,
 -109, -266, -266, -266, -187,    0, -237, -266, -266,    0,
 -171, -266, -212,    0,   -1,   -1,   -1,    0,    0,    0,
    0, -225, -237, -211, -225, -225, -266,    0, -266, -245,
 -210,   -1, -225,    0, -225, -225, -225,  -40, -266,    0,
 -225,  -61,    0, -162, -225,    0,    0,    0,    0,    0,
 -266, -225,  -58, -266, -225,    0,    0,    0,    0, -256,
 -119, -266, -111, -266, -225, -266, -271,  -89, -242,    0,
   -1, -225, -266, -266,   -1,    0, -225, -225, -227,    0,
   -1, -185, -184,    0, -254, -225,    0,    0, -225,    0,
    0,    0, 1254, -223,    0,  -63,    0,   -1,    0,    0,
 -266, -266, -266,    0, -266, -165, -266, -237, -237,    0,
   -1,    0, -225, -225, -225, -254, -157, -225,    0,    0,
    0,    0, -266, -225,};
const short yyrindex[] =
	{                                     44,
    1,    1,    0,    0,  105,    0,    0,    0,  107,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    7,    0,    0,    0,    0,    0,    0,   13, -106,    0,
    0,    0,    8,  -15, -243,   10,    0,    0,    0,    0,
    0,    0,    0,   23,   28,    0,    0,    0,    0,    0,
   12,   91,    0, 1449,    0,    0,    0,    0,    0, -106,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
   15,    0,    0,    0,    0,    0,  454,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0, 1449, 1449, 1449,    0,    0,    0,
    0,  492,    0,    0,  530,  568,    0,    0,    0,    0,
    0,  -86,  622,    0,  685,  723,  761,    0,    0,    0,
  799,    0,    0,    0,  842,    0,    0,    0,    0,    0,
  905,  967,    0,    0,  174,    0,    0,    0,    0, 1001,
    0,    0,    0,    0, 1044,    0,  252,    0,    0,    0,
 1305, 1085,    0,    0,  280,    0, 1125,  363,    0,    0,
  -86, 1180, 1221,    0, -110, -108,    0,    0,  411,    0,
    0,    0,    0,    0,    0,    0,    0, 1305,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  280,    0,   50,   68,   78,   96,    0,  106,    0,    0,
    0,    0,    0,  124,};
const short yygindex[] =
	{                                      0,
  -81,  -96, 1468,    0,    0,   24,  110,  -30,    0,    0,
    0,    0,    0,    6,    0,   52,    0,    0,    0,    0,
    0,  -64,    0,    0,    0,    0,    0,    0,    0,    0,
    0,  -37,    0,   55,    0,    0,   42,
};
#define YYTABLESIZE 1744
const short yytable[] =
	{                                     152,
  117,  149,  156,  161,    1,   39,   73,    8,    1,   69,
  169,  165,   60,  122,   63,  130,   18,   23,  117,   24,
   12,   17,   33,    4,  109,  159,  117,  184,   56,   66,
  160,  140,   29,   29,   53,  170,   66,   30,  117,   30,
   57,   33,   34,    3,   58,   48,   49,   50,   51,   52,
   60,   53,  144,    2,   78,   79,   65,    2,   32,   67,
   30,  200,  117,  172,  173,   18,   23,   41,   24,   71,
   17,   33,   42,  109,   45,   76,   47,   68,   30,  178,
   53,   29,  189,  190,   64,  111,   30,   69,  113,  114,
  117,   75,  128,  134,  136,  141,  146,   83,  154,  207,
   31,  181,  182,  213,    2,   60,    1,   34,   67,  212,
  137,  138,  139,    9,   70,   73,  209,  210,  188,   28,
  171,   74,  110,    0,    0,  117,   68,  147,    0,    0,
    0,    0,    0,   72,    0,    0,   69,   33,    0,   36,
    0,   36,    0,    0,    0,    0,    0,   29,    0,   31,
  117,   12,   30,    0,   60,    0,    0,  163,   60,    0,
   63,    0,    0,    0,   73,    0,  174,    0,    0,  118,
  177,  119,  164,   60,   67,   63,  180,    0,   37,   38,
   37,   38,   72,  100,  120,  121,   53,   65,    0,  117,
  117,  119,   68,  202,  117,    0,   30,    0,  191,    0,
    0,    0,   69,    0,  120,  121,  211,  117,  117,  192,
    0,    0,    0,    0,    0,   31,    0,    0,    0,    0,
   60,  193,    0,  194,  195,  196,    0,    0,    0,  197,
   73,    0,  100,    0,    0,    0,    0,    0,  198,    0,
  199,    0,    0,    0,   53,    0,    0,   53,   72,    0,
    0,    0,    0,    0,    0,    0,  117,  117,  117,  117,
  117,  102,  117,  117,  117,  148,  117,    0,  117,   33,
  117,  117,  117,  117,  117,  117,  117,  117,  117,   29,
    0,  117,  117,  117,   30,  117,  117,  117,  117,  117,
    0,  117,  117,  117,  117,  117,  117,  117,  100,    3,
    0,  117,  117,  117,  117,    0,  117,    3,   33,   33,
  102,   67,    0,    3,    0,    3,    0,    0,   29,   29,
    3,    0,   67,   30,   30,    3,    3,    0,    3,   68,
    0,    0,    0,    0,   67,    3,   67,   67,   67,   69,
   68,    0,   67,    0,    3,    0,    3,   31,    0,    3,
   69,   67,   68,   67,   68,   68,   68,   60,    0,    0,
   68,    0,   69,    0,   69,   69,   69,   73,   60,   68,
   69,   68,   99,    0,    0,    0,  102,    0,   73,   69,
   60,   69,   60,   60,   60,   72,   31,   31,   60,    0,
   73,    0,   73,   73,   73,    0,   72,   60,   73,   60,
    0,    0,    0,    0,  117,    0,    0,   73,   72,   73,
   72,   72,   72,    0,    0,    0,   72,    0,    0,    0,
  103,   99,    0,    0,    0,   72,    0,   72,    0,  100,
    0,  100,  100,  100,    0,  100,  100,    0,    0,  100,
    0,  100,    0,    0,  100,    0,  100,  100,  100,  100,
  100,  100,    0,    0,  100,    0,    0,    0,    0,  100,
    0,    0,  100,   84,  100,    0,    0,  100,  100,  103,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,   99,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,   43,    0,    0,    0,    0,    0,  102,    0,  102,
  102,  102,   84,  102,  102,    0,    0,  102,    0,  102,
    0,    0,  102,    0,  102,  102,  102,  102,  102,  102,
    0,    0,  102,    0,    0,  103,    0,  102,    0,   44,
  102,  117,  102,    0,    0,  102,  102,    0,    0,    0,
   43,    0,  117,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,  117,    0,  117,  117,  117,    0,
    0,    0,  117,    0,    0,    0,    0,   45,   84,    0,
    0,  117,    0,  117,    0,    0,    0,    0,   44,    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,   43,    0,   99,    0,
   99,   99,   99,    0,   99,   99,   45,    0,   99,    0,
   99,   96,    0,   99,    0,   99,   99,   99,   99,   99,
   99,    0,    0,   99,    0,    0,    0,    0,   99,    0,
    0,   99,    0,   99,   44,    0,   99,   99,    0,    0,
    0,    0,    0,    0,    0,    0,  103,    0,  103,  103,
  103,    0,  103,  103,    0,    0,  103,    0,  103,    0,
   96,  103,    0,  103,  103,  103,  103,  103,  103,    0,
    0,  103,   45,    0,   87,    0,  103,    0,    0,  103,
    0,  103,    0,    0,  103,  103,    0,    0,    0,   84,
    0,   84,   84,   84,    0,   84,   84,    0,    0,   84,
    0,   84,    0,    0,   84,    0,   84,   84,   84,   84,
   84,   84,   46,    0,   84,    0,    0,    0,    0,   84,
    0,    0,   84,   87,   84,    0,   96,   43,   84,   43,
   43,   43,    0,   43,   43,    0,    0,   43,    0,   43,
    0,    0,   43,    0,   43,   43,   43,   43,   43,   43,
   88,    0,   43,    0,    0,    0,    0,   43,    0,    0,
   43,   46,   43,    0,    0,   44,   43,   44,   44,   44,
    0,   44,   44,    0,    0,   44,    0,   44,    0,    0,
   44,    0,   44,   44,   44,   44,   44,   44,   47,   87,
   44,    0,    0,    0,    0,   44,    0,    0,   44,   88,
   44,    0,    0,   45,   44,   45,   45,   45,    0,   45,
   45,    0,    0,   45,    0,   45,    0,    0,   45,    0,
   45,   45,   45,   45,   45,   45,    0,   46,   45,    0,
    0,   91,    0,   45,    0,    0,   45,   47,   45,    0,
    0,    0,   45,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,   96,    0,   96,
   96,   96,    0,   96,   96,   88,    0,   96,    0,   96,
    0,    0,   96,    0,   96,   96,   96,   96,   96,   96,
   91,    0,   96,    0,    0,    0,    0,   96,    0,    0,
   96,    0,   96,    0,   83,    0,   96,    0,    0,    0,
    0,    0,    0,   47,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
   87,    0,   87,   87,   87,    0,   87,   87,    0,    0,
   87,    0,   87,    0,    0,   87,    0,   87,   87,   87,
   87,   87,   87,   83,    0,   87,   91,    0,    0,    0,
   87,    0,    0,   87,    0,   87,   85,    0,   46,   87,
   46,   46,   46,    0,   46,   46,    0,    0,   46,    0,
   46,    0,    0,   46,    0,   46,   46,   46,   46,   46,
   46,    0,    0,   46,    0,    0,    0,    0,   46,    0,
   49,   46,    0,   46,    0,    0,   88,   46,   88,   88,
   88,    0,   88,   88,    0,   85,   88,    0,   88,   83,
    0,   88,    0,   88,   88,   88,   88,   88,   88,    0,
    0,   88,    0,    0,    0,    0,   88,    0,    0,   88,
    0,   88,    0,   82,   47,   88,   47,   47,   47,   49,
   47,   47,    0,    0,   47,    0,   47,    0,    0,   47,
    0,   47,   47,   47,   47,   47,   47,    0,    0,   47,
    0,    0,    0,    0,   47,    0,    0,   47,    0,   47,
    0,   85,    0,   47,   48,    0,    0,   91,    0,   91,
   91,   91,   82,   91,   91,    0,    0,   91,    0,   91,
    0,    0,   91,    0,   91,   91,   91,   91,   91,   91,
    0,    0,   91,    0,    0,   49,    0,   91,    0,    0,
   91,    0,   91,    0,   90,    0,   91,    0,    0,    0,
    0,    0,    0,   48,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
   83,    0,   83,   83,   83,    0,   83,   83,   82,    0,
   83,    0,   83,    0,    0,   83,    0,   83,   83,   83,
   83,   83,   83,   90,    0,   83,    0,    0,    0,   50,
   83,    0,    0,   83,    0,   83,    0,    0,    0,   83,
    0,    0,    0,    0,    0,    0,    0,    0,    0,   48,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,   85,    0,   85,   85,   85,    0,   85,   85,
   51,    0,   85,    0,   85,    0,    0,   85,   50,   85,
   85,   85,   85,   85,   85,    0,    0,   85,    0,   90,
    0,    0,   85,    0,    0,   85,   49,   85,   49,   49,
   49,   85,   49,   49,    0,    0,   49,    0,   49,    0,
    0,   49,    0,   49,   49,   49,   49,   49,   49,   51,
    0,   49,    0,    0,    0,    0,   49,    0,    0,   49,
    0,   49,    0,    0,    0,   49,    0,    0,    0,   82,
    0,   82,   82,   82,   50,   82,   82,    0,    0,   82,
    0,   82,    0,    0,   82,    0,   82,   82,   82,   82,
   82,   82,    0,    0,   82,    0,    0,    0,    0,   82,
    0,    0,   82,    0,   82,    0,    0,    0,   82,    0,
   48,    0,   48,   48,   48,   51,   48,   48,    0,    0,
   48,    0,   48,    0,    0,   48,    0,   48,   48,   48,
   48,   48,   48,    0,    0,   48,    0,    0,    0,    0,
   48,    0,    0,   48,    0,   48,    0,    0,  187,   48,
   90,    0,   90,   90,   90,    0,   90,   90,    0,    0,
   90,    0,   90,    0,    0,   90,    0,   90,   90,   90,
   90,   90,   90,    0,    0,   90,    0,    0,    0,    0,
   90,    0,    0,   90,    0,   90,    0,    0,    0,   90,
    0,    0,    0,    0,    0,    0,    0,    0,    0,  117,
    0,    0,    0,    0,    0,   50,    0,   50,   50,   50,
    0,   50,   50,    0,    0,   50,    0,   50,    0,    0,
   50,    0,   50,   50,   50,   50,   50,   50,    0,    0,
   50,    0,    0,    0,    0,   50,    0,    0,   50,    0,
   50,    0,    0,    0,   50,    0,   51,    0,   51,   51,
   51,    0,   51,   51,   43,   44,   51,   46,   51,    0,
    0,   51,    0,   51,   51,   51,   51,   51,   51,    0,
    0,   51,    0,   54,   55,    0,   51,    0,    0,   51,
    0,   51,   86,   87,   61,   51,    0,    0,    0,   90,
    0,   91,    0,   62,   92,    0,    0,   94,    0,    0,
   97,    0,    0,    0,    0,  104,    0,    0,    0,    0,
    0,    0,  101,    0,  102,    0,    0,    0,  103,    0,
    0,    0,  112,    0,    0,  115,  116,    0,  123,  125,
  126,  127,    0,  117,  117,  131,  132,    0,    0,  135,
  117,    0,  117,  117,    0,  117,    0,    0,  117,    0,
    0,  117,    0,    0,  142,    0,  143,  145,    0,    0,
    0,    0,    0,  117,    0,  117,  151,    0,    0,  117,
    0,    0,    0,    0,    0,    0,   10,    0,  155,    0,
    0,  157,    0,    0,   11,    0,    0,    0,    0,  162,
   12,  167,   13,  168,    0,    0,    0,   14,    0,    0,
  175,  176,   15,   16,    0,   17,  179,    0,    0,    0,
    0,    0,   18,    0,    0,    0,    0,    0,    0,    0,
    0,   19,    0,   20,    0,    0,   21,    0,  203,  204,
  205,    0,  206,    0,  208,    0,   84,    0,   85,   86,
   87,    0,   88,   89,    0,    0,   90,    0,   91,    0,
  214,   92,    0,   93,   94,   95,   96,   97,   98,    0,
    0,   99,    0,    0,    0,    0,  100,    0,    0,  101,
    0,  102,    0,    0,  117,  103,  117,  117,  117,    0,
  117,  117,    0,    0,  117,    0,  117,    0,    0,  117,
    0,  117,  117,  117,  117,  117,  117,    0,    0,  117,
    0,    0,    0,    0,  117,    0,    0,  117,    0,  117,
    0,    0,    0,  117,
};
const short yycheck[] =
	{                                      61,
    0,   42,   61,  123,   10,  123,  125,    2,   10,  125,
  282,  123,  123,  123,  123,   97,   10,   10,  125,   10,
  270,   10,   10,    0,   10,  282,  270,  282,  267,   60,
  287,  113,   10,   10,  306,  125,   67,   10,  125,  306,
  279,  279,  280,    0,   39,   22,   23,   24,   25,   26,
   45,  306,  298,   59,  306,  307,  306,   59,  306,   10,
  306,  125,  306,  306,  307,   59,   59,  307,   59,   64,
   59,   59,  307,   59,  123,   70,   61,   10,  306,  307,
  306,   59,  306,  307,  123,  125,   59,   10,  271,  290,
  300,   68,  280,  265,  307,  307,  307,   74,  261,  265,
   10,  287,  287,  261,    0,   10,    0,  123,   59,  206,
  105,  106,  107,    4,   63,   10,  198,  199,  183,  125,
  158,   67,   81,   -1,   -1,  125,   59,  122,   -1,   -1,
   -1,   -1,   -1,   10,   -1,   -1,   59,  125,   -1,  257,
   -1,  257,   -1,   -1,   -1,   -1,   -1,  125,   -1,   59,
  257,  270,  125,   -1,   59,   -1,   -1,  269,  269,   -1,
  269,   -1,   -1,   -1,   59,   -1,  161,   -1,   -1,  279,
  165,  281,  284,  284,  125,  284,  171,   -1,  296,  297,
  296,  297,   59,   10,  294,  295,  306,  306,   -1,  296,
  297,  281,  125,  188,  281,   -1,  306,   -1,  262,   -1,
   -1,   -1,  125,   -1,  294,  295,  201,  294,  295,  273,
   -1,   -1,   -1,   -1,   -1,  125,   -1,   -1,   -1,   -1,
  125,  285,   -1,  287,  288,  289,   -1,   -1,   -1,  293,
  125,   -1,   59,   -1,   -1,   -1,   -1,   -1,  302,   -1,
  304,   -1,   -1,   -1,  306,   -1,   -1,  306,  125,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  256,  257,  258,  259,
  260,   10,  262,  263,  264,  306,  266,   -1,  268,  257,
  270,  271,  272,  273,  274,  275,  276,  277,  278,  257,
   -1,  281,  282,  283,  257,  285,  286,  287,  288,  289,
   -1,  291,  292,  293,  294,  295,  296,  297,  125,  256,
   -1,  301,  302,  303,  304,   -1,  306,  264,  296,  297,
   59,  262,   -1,  270,   -1,  272,   -1,   -1,  296,  297,
  277,   -1,  273,  296,  297,  282,  283,   -1,  285,  262,
   -1,   -1,   -1,   -1,  285,  292,  287,  288,  289,  262,
  273,   -1,  293,   -1,  301,   -1,  303,  257,   -1,  306,
  273,  302,  285,  304,  287,  288,  289,  262,   -1,   -1,
  293,   -1,  285,   -1,  287,  288,  289,  262,  273,  302,
  293,  304,   10,   -1,   -1,   -1,  125,   -1,  273,  302,
  285,  304,  287,  288,  289,  262,  296,  297,  293,   -1,
  285,   -1,  287,  288,  289,   -1,  273,  302,  293,  304,
   -1,   -1,   -1,   -1,  125,   -1,   -1,  302,  285,  304,
  287,  288,  289,   -1,   -1,   -1,  293,   -1,   -1,   -1,
   10,   59,   -1,   -1,   -1,  302,   -1,  304,   -1,  256,
   -1,  258,  259,  260,   -1,  262,  263,   -1,   -1,  266,
   -1,  268,   -1,   -1,  271,   -1,  273,  274,  275,  276,
  277,  278,   -1,   -1,  281,   -1,   -1,   -1,   -1,  286,
   -1,   -1,  289,   10,  291,   -1,   -1,  294,  295,   59,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,  125,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   10,   -1,   -1,   -1,   -1,   -1,  256,   -1,  258,
  259,  260,   59,  262,  263,   -1,   -1,  266,   -1,  268,
   -1,   -1,  271,   -1,  273,  274,  275,  276,  277,  278,
   -1,   -1,  281,   -1,   -1,  125,   -1,  286,   -1,   10,
  289,  262,  291,   -1,   -1,  294,  295,   -1,   -1,   -1,
   59,   -1,  273,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,  285,   -1,  287,  288,  289,   -1,
   -1,   -1,  293,   -1,   -1,   -1,   -1,   10,  125,   -1,
   -1,  302,   -1,  304,   -1,   -1,   -1,   -1,   59,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  125,   -1,  256,   -1,
  258,  259,  260,   -1,  262,  263,   59,   -1,  266,   -1,
  268,   10,   -1,  271,   -1,  273,  274,  275,  276,  277,
  278,   -1,   -1,  281,   -1,   -1,   -1,   -1,  286,   -1,
   -1,  289,   -1,  291,  125,   -1,  294,  295,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  256,   -1,  258,  259,
  260,   -1,  262,  263,   -1,   -1,  266,   -1,  268,   -1,
   59,  271,   -1,  273,  274,  275,  276,  277,  278,   -1,
   -1,  281,  125,   -1,   10,   -1,  286,   -1,   -1,  289,
   -1,  291,   -1,   -1,  294,  295,   -1,   -1,   -1,  256,
   -1,  258,  259,  260,   -1,  262,  263,   -1,   -1,  266,
   -1,  268,   -1,   -1,  271,   -1,  273,  274,  275,  276,
  277,  278,   10,   -1,  281,   -1,   -1,   -1,   -1,  286,
   -1,   -1,  289,   59,  291,   -1,  125,  256,  295,  258,
  259,  260,   -1,  262,  263,   -1,   -1,  266,   -1,  268,
   -1,   -1,  271,   -1,  273,  274,  275,  276,  277,  278,
   10,   -1,  281,   -1,   -1,   -1,   -1,  286,   -1,   -1,
  289,   59,  291,   -1,   -1,  256,  295,  258,  259,  260,
   -1,  262,  263,   -1,   -1,  266,   -1,  268,   -1,   -1,
  271,   -1,  273,  274,  275,  276,  277,  278,   10,  125,
  281,   -1,   -1,   -1,   -1,  286,   -1,   -1,  289,   59,
  291,   -1,   -1,  256,  295,  258,  259,  260,   -1,  262,
  263,   -1,   -1,  266,   -1,  268,   -1,   -1,  271,   -1,
  273,  274,  275,  276,  277,  278,   -1,  125,  281,   -1,
   -1,   10,   -1,  286,   -1,   -1,  289,   59,  291,   -1,
   -1,   -1,  295,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,  256,   -1,  258,
  259,  260,   -1,  262,  263,  125,   -1,  266,   -1,  268,
   -1,   -1,  271,   -1,  273,  274,  275,  276,  277,  278,
   59,   -1,  281,   -1,   -1,   -1,   -1,  286,   -1,   -1,
  289,   -1,  291,   -1,   10,   -1,  295,   -1,   -1,   -1,
   -1,   -1,   -1,  125,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  256,   -1,  258,  259,  260,   -1,  262,  263,   -1,   -1,
  266,   -1,  268,   -1,   -1,  271,   -1,  273,  274,  275,
  276,  277,  278,   59,   -1,  281,  125,   -1,   -1,   -1,
  286,   -1,   -1,  289,   -1,  291,   10,   -1,  256,  295,
  258,  259,  260,   -1,  262,  263,   -1,   -1,  266,   -1,
  268,   -1,   -1,  271,   -1,  273,  274,  275,  276,  277,
  278,   -1,   -1,  281,   -1,   -1,   -1,   -1,  286,   -1,
   10,  289,   -1,  291,   -1,   -1,  256,  295,  258,  259,
  260,   -1,  262,  263,   -1,   59,  266,   -1,  268,  125,
   -1,  271,   -1,  273,  274,  275,  276,  277,  278,   -1,
   -1,  281,   -1,   -1,   -1,   -1,  286,   -1,   -1,  289,
   -1,  291,   -1,   10,  256,  295,  258,  259,  260,   59,
  262,  263,   -1,   -1,  266,   -1,  268,   -1,   -1,  271,
   -1,  273,  274,  275,  276,  277,  278,   -1,   -1,  281,
   -1,   -1,   -1,   -1,  286,   -1,   -1,  289,   -1,  291,
   -1,  125,   -1,  295,   10,   -1,   -1,  256,   -1,  258,
  259,  260,   59,  262,  263,   -1,   -1,  266,   -1,  268,
   -1,   -1,  271,   -1,  273,  274,  275,  276,  277,  278,
   -1,   -1,  281,   -1,   -1,  125,   -1,  286,   -1,   -1,
  289,   -1,  291,   -1,   10,   -1,  295,   -1,   -1,   -1,
   -1,   -1,   -1,   59,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  256,   -1,  258,  259,  260,   -1,  262,  263,  125,   -1,
  266,   -1,  268,   -1,   -1,  271,   -1,  273,  274,  275,
  276,  277,  278,   59,   -1,  281,   -1,   -1,   -1,   10,
  286,   -1,   -1,  289,   -1,  291,   -1,   -1,   -1,  295,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  125,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,  256,   -1,  258,  259,  260,   -1,  262,  263,
   10,   -1,  266,   -1,  268,   -1,   -1,  271,   59,  273,
  274,  275,  276,  277,  278,   -1,   -1,  281,   -1,  125,
   -1,   -1,  286,   -1,   -1,  289,  256,  291,  258,  259,
  260,  295,  262,  263,   -1,   -1,  266,   -1,  268,   -1,
   -1,  271,   -1,  273,  274,  275,  276,  277,  278,   59,
   -1,  281,   -1,   -1,   -1,   -1,  286,   -1,   -1,  289,
   -1,  291,   -1,   -1,   -1,  295,   -1,   -1,   -1,  256,
   -1,  258,  259,  260,  125,  262,  263,   -1,   -1,  266,
   -1,  268,   -1,   -1,  271,   -1,  273,  274,  275,  276,
  277,  278,   -1,   -1,  281,   -1,   -1,   -1,   -1,  286,
   -1,   -1,  289,   -1,  291,   -1,   -1,   -1,  295,   -1,
  256,   -1,  258,  259,  260,  125,  262,  263,   -1,   -1,
  266,   -1,  268,   -1,   -1,  271,   -1,  273,  274,  275,
  276,  277,  278,   -1,   -1,  281,   -1,   -1,   -1,   -1,
  286,   -1,   -1,  289,   -1,  291,   -1,   -1,  125,  295,
  256,   -1,  258,  259,  260,   -1,  262,  263,   -1,   -1,
  266,   -1,  268,   -1,   -1,  271,   -1,  273,  274,  275,
  276,  277,  278,   -1,   -1,  281,   -1,   -1,   -1,   -1,
  286,   -1,   -1,  289,   -1,  291,   -1,   -1,   -1,  295,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  125,
   -1,   -1,   -1,   -1,   -1,  256,   -1,  258,  259,  260,
   -1,  262,  263,   -1,   -1,  266,   -1,  268,   -1,   -1,
  271,   -1,  273,  274,  275,  276,  277,  278,   -1,   -1,
  281,   -1,   -1,   -1,   -1,  286,   -1,   -1,  289,   -1,
  291,   -1,   -1,   -1,  295,   -1,  256,   -1,  258,  259,
  260,   -1,  262,  263,   17,   18,  266,   20,  268,   -1,
   -1,  271,   -1,  273,  274,  275,  276,  277,  278,   -1,
   -1,  281,   -1,   36,   37,   -1,  286,   -1,   -1,  289,
   -1,  291,  259,  260,   47,  295,   -1,   -1,   -1,  266,
   -1,  268,   -1,   56,  271,   -1,   -1,  274,   -1,   -1,
  277,   -1,   -1,   -1,   -1,  125,   -1,   -1,   -1,   -1,
   -1,   -1,  289,   -1,  291,   -1,   -1,   -1,  295,   -1,
   -1,   -1,   85,   -1,   -1,   88,   89,   -1,   91,   92,
   93,   94,   -1,  259,  260,   98,   99,   -1,   -1,  102,
  266,   -1,  268,  125,   -1,  271,   -1,   -1,  274,   -1,
   -1,  277,   -1,   -1,  117,   -1,  119,  120,   -1,   -1,
   -1,   -1,   -1,  289,   -1,  291,  129,   -1,   -1,  295,
   -1,   -1,   -1,   -1,   -1,   -1,  256,   -1,  141,   -1,
   -1,  144,   -1,   -1,  264,   -1,   -1,   -1,   -1,  152,
  270,  154,  272,  156,   -1,   -1,   -1,  277,   -1,   -1,
  163,  164,  282,  283,   -1,  285,  169,   -1,   -1,   -1,
   -1,   -1,  292,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,  301,   -1,  303,   -1,   -1,  306,   -1,  191,  192,
  193,   -1,  195,   -1,  197,   -1,  256,   -1,  258,  259,
  260,   -1,  262,  263,   -1,   -1,  266,   -1,  268,   -1,
  213,  271,   -1,  273,  274,  275,  276,  277,  278,   -1,
   -1,  281,   -1,   -1,   -1,   -1,  286,   -1,   -1,  289,
   -1,  291,   -1,   -1,  256,  295,  258,  259,  260,   -1,
  262,  263,   -1,   -1,  266,   -1,  268,   -1,   -1,  271,
   -1,  273,  274,  275,  276,  277,  278,   -1,   -1,  281,
   -1,   -1,   -1,   -1,  286,   -1,   -1,  289,   -1,  291,
   -1,   -1,   -1,  295,
};
#define YYFINAL 3
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 307
#if YYDEBUG
const char * const yyname[] =
	{
"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,
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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"ACCESS","ALIAS","AUTO","BLOCK","CA","CERT","CGI","CHROOT","CLIENT","DEFAULT",
"FACILITY","FASTCGI","FOR_HOST","INCLUDE","INDEX","IPV6","KEY","LANG","LISTEN",
"LOCATION","LOG","OCSP","OFF","ON","PARAM","PORT","PREFORK","PROTO","PROTOCOLS",
"PROXY","PROXYV1","RELAY_TO","REQUIRE","RETURN","ROOT","SERVER","SNI","SOCKET",
"STRIP","STYLE","SYSLOG","TCP","TOEXT","TYPE","TYPES","USE_TLS","USER",
"VERIFYNAME","ERROR","STRING","NUM",
};
const char * const yyrule[] =
	{"$accept : grammar",
"grammar : nl conf",
"grammar : conf",
"conf :",
"conf : conf include nl",
"conf : conf varset nl",
"conf : conf option nl",
"conf : conf vhost nl",
"conf : conf types nl",
"conf : conf error nl",
"include : INCLUDE STRING",
"bool : ON",
"bool : OFF",
"string : string STRING",
"string : STRING",
"numberstring : NUM",
"numberstring : STRING",
"varset : STRING '=' string",
"option : CHROOT string",
"option : IPV6 bool",
"option : log",
"option : PORT NUM",
"option : PREFORK NUM",
"option : PROTOCOLS string",
"option : USER string",
"log : LOG '{' optnl logopts '}'",
"log : LOG logopt",
"logopts :",
"logopts : logopts logopt optnl",
"logopt : ACCESS string",
"logopt : STYLE string",
"logopt : SYSLOG FACILITY string",
"logopt : SYSLOG OFF",
"logopt : SYSLOG",
"$$1 :",
"vhost : SERVER string $$1 '{' optnl servbody '}'",
"vhost : error '}'",
"servbody :",
"servbody : servbody servopt optnl",
"servbody : servbody location optnl",
"servbody : servbody proxy optnl",
"listen_addr : '*'",
"listen_addr : STRING",
"servopt : ALIAS string",
"servopt : CERT string",
"servopt : CGI string",
"servopt : KEY string",
"servopt : OCSP string",
"servopt : PARAM string '=' string",
"servopt : LISTEN ON listen_addr",
"servopt : LISTEN ON listen_addr PORT STRING",
"servopt : LISTEN ON listen_addr PORT NUM",
"servopt : LISTEN ON listen_addr PROXYV1",
"servopt : LISTEN ON listen_addr PORT STRING PROXYV1",
"servopt : LISTEN ON listen_addr PORT NUM PROXYV1",
"servopt : locopt",
"$$2 :",
"proxy : PROXY $$2 proxy_matches '{' optnl proxy_opts '}'",
"proxy_matches :",
"proxy_matches : proxy_matches proxy_match",
"proxy_port :",
"proxy_port : PORT STRING",
"proxy_port : PORT NUM",
"proxy_match : PROTO string",
"proxy_match : FOR_HOST string proxy_port",
"proxy_opts :",
"proxy_opts : proxy_opts proxy_opt optnl",
"proxy_opt : CERT string",
"proxy_opt : KEY string",
"proxy_opt : PROTOCOLS string",
"proxy_opt : PROXYV1",
"proxy_opt : RELAY_TO string proxy_port",
"proxy_opt : REQUIRE CLIENT CA string",
"proxy_opt : SNI string",
"proxy_opt : USE_TLS bool",
"proxy_opt : VERIFYNAME bool",
"$$3 :",
"location : LOCATION $$3 string '{' optnl locopts '}'",
"location : error '}'",
"locopts :",
"locopts : locopts locopt optnl",
"locopt : AUTO INDEX bool",
"locopt : BLOCK RETURN NUM string",
"locopt : BLOCK RETURN NUM",
"locopt : BLOCK",
"locopt : DEFAULT TYPE string",
"locopt : fastcgi",
"locopt : INDEX string",
"locopt : LANG string",
"locopt : LOG bool",
"locopt : REQUIRE CLIENT CA string",
"locopt : ROOT string",
"locopt : STRIP NUM",
"fastcgi : FASTCGI '{' optnl fastcgiopts '}'",
"fastcgi : FASTCGI fastcgiopt",
"fastcgi : FASTCGI OFF",
"fastcgi : FASTCGI string",
"fastcgiopts :",
"fastcgiopts : fastcgiopts fastcgiopt optnl",
"fastcgiopt : PARAM string '=' string",
"fastcgiopt : SOCKET string",
"fastcgiopt : SOCKET TCP string PORT NUM",
"fastcgiopt : SOCKET TCP string",
"fastcgiopt : SOCKET TCP string PORT string",
"fastcgiopt : STRIP NUM",
"types : TYPES '{' optnl mediaopts_l '}'",
"mediaopts_l : mediaopts_l mediaoptsl nl",
"mediaopts_l : mediaoptsl nl",
"$$4 :",
"mediaoptsl : STRING $$4 medianames_l",
"mediaoptsl : include",
"medianames_l : medianames_l medianamesl",
"medianames_l : medianamesl",
"medianamesl : numberstring",
"nl : '\\n' optnl",
"nl : ';' optnl",
"optnl : nl",
"optnl :",
};
#endif
#ifdef YYSTACKSIZE
#undef YYMAXDEPTH
#define YYMAXDEPTH YYSTACKSIZE
#else
#ifdef YYMAXDEPTH
#define YYSTACKSIZE YYMAXDEPTH
#else
#define YYSTACKSIZE 10000
#define YYMAXDEPTH 10000
#endif
#endif
#define YYINITSTACKSIZE 200
/* LINTUSED */
int yydebug;
int yynerrs;
int yyerrflag;
int yychar;
short *yyssp;
YYSTYPE *yyvsp;
YYSTYPE yyval;
YYSTYPE yylval;
short *yyss;
short *yysslim;
YYSTYPE *yyvs;
unsigned int yystacksize;
int yyparse(void);
#line 702 "parse.y"

static const struct keyword {
	const char *word;
	int token;
} keywords[] = {
	/* these MUST be sorted */
	{"access", ACCESS},
	{"alias", ALIAS},
	{"auto", AUTO},
	{"block", BLOCK},
	{"ca", CA},
	{"cert", CERT},
	{"cgi", CGI},
	{"chroot", CHROOT},
	{"client", CLIENT},
	{"default", DEFAULT},
	{"facility", FACILITY},
	{"fastcgi", FASTCGI},
	{"for-host", FOR_HOST},
	{"include", INCLUDE},
	{"index", INDEX},
	{"ipv6", IPV6},
	{"key", KEY},
	{"lang", LANG},
	{"listen", LISTEN},
	{"location", LOCATION},
	{"log", LOG},
	{"ocsp", OCSP},
	{"off", OFF},
	{"on", ON},
	{"param", PARAM},
	{"port", PORT},
	{"prefork", PREFORK},
	{"proto", PROTO},
	{"protocols", PROTOCOLS},
	{"proxy", PROXY},
	{"proxy-v1", PROXYV1},
	{"relay-to", RELAY_TO},
	{"require", REQUIRE},
	{"return", RETURN},
	{"root", ROOT},
	{"server", SERVER},
	{"sni", SNI},
	{"socket", SOCKET},
	{"strip", STRIP},
	{"style", STYLE},
	{"syslog", SYSLOG},
	{"tcp", TCP},
	{"to-ext", TOEXT},
	{"type", TYPE},
	{"types", TYPES},
	{"use-tls", USE_TLS},
	{"user", USER},
	{"verifyname", VERIFYNAME},
};

void
yyerror(const char *msg, ...)
{
	va_list ap;

	file->errors++;

	va_start(ap, msg);
	fprintf(stderr, "%s:%d error: ", config_path, yylval.lineno);
	vfprintf(stderr, msg, ap);
	fprintf(stderr, "\n");
	va_end(ap);
}

void
yywarn(const char *msg, ...)
{
	va_list ap;

	va_start(ap, msg);
	fprintf(stderr, "%s:%d warning: ", config_path, yylval.lineno);
	vfprintf(stderr, msg, ap);
	fprintf(stderr, "\n");
	va_end(ap);
}

int
kw_cmp(const void *k, const void *e)
{
	return strcmp(k, ((struct keyword *)e)->word);
}

int
lookup(char *s)
{
	const struct keyword	*p;

	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
	    sizeof(keywords[0]), kw_cmp);

	if (p)
		return p->token;
	else
		return STRING;
}

#define START_EXPAND	1
#define DONE_EXPAND	2

static int	expanding;

int
igetc(void)
{
	int	c;

	while (1) {
		if (file->ungetpos > 0)
			c = file->ungetbuf[--file->ungetpos];
		else
			c = getc(file->stream);

		if (c == START_EXPAND)
			expanding = 1;
		else if (c == DONE_EXPAND)
			expanding = 0;
		else
			break;
	}
	return c;
}

int
lgetc(int quotec)
{
	int		c, next;

	if (quotec) {
		if ((c = igetc()) == EOF) {
			yyerror("reached end of file while parsing "
			    "quoted string");
			if (file == topfile || popfile() == EOF)
				return EOF;
			return quotec;
		}
		return c;
	}

	while ((c = igetc()) == '\\') {
		next = igetc();
		if (next != '\n') {
			c = next;
			break;
		}
		yylval.lineno = file->lineno;
		file->lineno++;
	}

	if (c == EOF) {
		/*
		 * Fake EOL when hit EOF for the first time. This gets line
		 * count right if last line in included file is syntactically
		 * invalid and has no newline.
		 */
		if (file->eof_reached == 0) {
			file->eof_reached = 1;
			return '\n';
		}
		while (c == EOF) {
			if (file == topfile || popfile() == EOF)
				return EOF;
			c = igetc();
		}
	}
	return c;
}

void
lungetc(int c)
{
	if (c == EOF)
		return;

	if (file->ungetpos >= file->ungetsize) {
		void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
		if (p == NULL)
			fatal("lungetc");
		file->ungetbuf = p;
		file->ungetsize *= 2;
	}
	file->ungetbuf[file->ungetpos++] = c;
}

int
findeol(void)
{
	int	c;

	/* Skip to either EOF or the first real EOL. */
	while (1) {
		c = lgetc(0);
		if (c == '\n') {
			file->lineno++;
			break;
		}
		if (c == EOF)
			break;
	}
	return ERROR;
}

int
yylex(void)
{
	char	 buf[8096];
	char	*p, *val;
	int	 quotec, next, c;
	int	 token;

top:
	p = buf;
	while ((c = lgetc(0)) == ' ' || c == '\t')
		; /* nothing */

	yylval.lineno = file->lineno;
	if (c == '#')
		while ((c = lgetc(0)) != '\n' && c != EOF)
			; /* nothing */
	if (c == '$' && !expanding) {
		while (1) {
			if ((c = lgetc(0)) == EOF)
				return 0;
			if (p + 1 >= buf + sizeof(buf) -1) {
				yyerror("string too long");
				return findeol();
			}
			if (isalnum(c) || c == '_') {
				*p++ = c;
				continue;
			}
			*p = '\0';
			lungetc(c);
			break;
		}
		val = symget(buf);
		if (val == NULL) {
			yyerror("macro `%s' not defined", buf);
			return findeol();
		}
		yylval.v.string = xstrdup(val);
		return STRING;
	}
	if (c == '@' && !expanding) {
		while (1) {
			if ((c = lgetc(0)) == EOF)
				return 0;

			if (p + 1 >= buf + sizeof(buf) - 1) {
				yyerror("string too long");
				return findeol();
			}
			if (isalnum(c) || c == '_') {
				*p++ = c;
				continue;
			}
			*p = '\0';
			lungetc(c);
			break;
		}
		val = symget(buf);
		if (val == NULL) {
			yyerror("macro '%s' not defined", buf);
			return findeol();
		}
		p = val + strlen(val) - 1;
		lungetc(DONE_EXPAND);
		while (p >= val) {
			lungetc(*p);
			p--;
		}
		lungetc(START_EXPAND);
		goto top;
	}

	switch (c) {
	case '\'':
	case '"':
		quotec = c;
		while (1) {
			if ((c = lgetc(quotec)) == EOF)
				return 0;
			if (c == '\n') {
				file->lineno++;
				continue;
			} else if (c == '\\') {
				if ((next = lgetc(quotec)) == EOF)
					return (0);
				if (next == quotec || next == ' ' ||
				    next == '\t')
					c = next;
				else if (next == '\n') {
					file->lineno++;
					continue;
				} else
					lungetc(next);
			} else if (c == quotec) {
				*p = '\0';
				break;
			} else if (c == '\0') {
				yyerror("invalid syntax");
				return findeol();
			}
			if (p + 1 >= buf + sizeof(buf) - 1) {
				yyerror("string too long");
				return findeol();
			}
			*p++ = c;
		}
		yylval.v.string = strdup(buf);
		if (yylval.v.string == NULL)
			fatal("yylex: strdup");
		return STRING;
	}

#define allowed_to_end_number(x) \
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')

	if (c == '-' || isdigit(c)) {
		do {
			*p++ = c;
			if ((size_t)(p-buf) >= sizeof(buf)) {
				yyerror("string too long");
				return findeol();
			}
		} while ((c = lgetc(0)) != 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 NUM;
		} 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 != '=' && x != '#' && \
	x != ',' && x != ';'))

	if (isalnum(c) || c == ':' || c == '_') {
		do {
			*p++ = c;
			if ((size_t)(p-buf) >= sizeof(buf)) {
				yyerror("string too long");
				return findeol();
			}
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
		lungetc(c);
		*p = '\0';
		if ((token = lookup(buf)) == STRING)
			yylval.v.string = xstrdup(buf);
		return token;
	}
	if (c == '\n') {
		yylval.lineno = file->lineno;
		file->lineno++;
	}
	if (c == EOF)
		return 0;
	return c;
}

struct file *
pushfile(const char *name, int secret)
{
	struct file	*nfile;

	nfile = xcalloc(1, sizeof(*nfile));
	nfile->name = xstrdup(name);
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
		log_warn("can't open %s", nfile->name);
		free(nfile->name);
		free(nfile);
		return NULL;
	}
	nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
	nfile->ungetsize = 16;
	nfile->ungetbuf = xcalloc(1, nfile->ungetsize);
	TAILQ_INSERT_TAIL(&files, nfile, entry);
	return nfile;
}

int
popfile(void)
{
	struct file	*prev;

	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
		prev->errors += file->errors;

	TAILQ_REMOVE(&files, file, entry);
	fclose(file->stream);
	free(file->name);
	free(file->ungetbuf);
	free(file);
	file = prev;
	return file ? 0 : EOF;
}

int
parse_conf(struct conf *c, const char *filename)
{
	struct sym		*sym, *next;

	default_host = NULL;
	default_port = 1965;

	conf = c;

	file = pushfile(filename, 0);
	if (file == NULL)
		return -1;
	topfile = file;

	yyparse();
	errors = file->errors;
	popfile();

	/* Free macros and check which have not been used. */
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
		/* TODO: warn if !sym->used */
		if (!sym->persist) {
			free(sym->name);
			free(sym->val);
			TAILQ_REMOVE(&symhead, sym, entry);
			free(sym);
		}
	}

	if (errors)
		return -1;
	return 0;
}

int
symset(const char *name, const char *val, int persist)
{
	struct sym *sym;

	TAILQ_FOREACH(sym, &symhead, entry) {
		if (!strcmp(name, sym->name))
			break;
	}

	if (sym != NULL) {
		if (sym->persist)
			return 0;
		else {
			free(sym->name);
			free(sym->val);
			TAILQ_REMOVE(&symhead, sym, entry);
			free(sym);
		}
	}

	sym = xcalloc(1, sizeof(*sym));
	sym->name = xstrdup(name);
	sym->val = xstrdup(val);
	sym->used = 0;
	sym->persist = persist;

	TAILQ_INSERT_TAIL(&symhead, sym, entry);
	return 0;
}

int
cmdline_symset(char *s)
{
	char	*sym, *val;
	int	 ret;

	if ((val = strrchr(s, '=')) == NULL)
		return -1;
	sym = xcalloc(1, val - s + 1);
	memcpy(sym, s, val - s);
	ret = symset(sym, val + 1, 1);
	free(sym);
	return ret;
}

char *
symget(const char *nam)
{
	struct sym	*sym;

	TAILQ_FOREACH(sym, &symhead, entry) {
		if (strcmp(nam, sym->name) == 0) {
			sym->used = 1;
			return sym->val;
		}
	}
	return NULL;
}

char *
ensure_absolute_path(char *path)
{
	if (path == NULL || *path != '/')
		yyerror("not an absolute path: %s", path);
	return path;
}

int
check_block_code(int n)
{
	if (n < 10 || n >= 70 || (n >= 20 && n <= 29))
		yyerror("invalid block code %d", n);
	return n;
}

char *
check_block_fmt(char *fmt)
{
	char *s;

	for (s = fmt; *s; ++s) {
		if (*s != '%')
			continue;
		switch (*++s) {
		case '%':
		case 'p':
		case 'q':
		case 'P':
		case 'N':
			break;
		default:
			yyerror("invalid format specifier %%%c", *s);
		}
	}

	return fmt;
}

int
check_strip_no(int n)
{
	if (n <= 0)
		yyerror("invalid strip number %d", n);
	return n;
}

int
check_prefork_num(int n)
{
	if (n <= 0 || n >= PROC_MAX_INSTANCES)
		yyerror("invalid prefork number %d", n);
	return n;
}

void
advance_loc(void)
{
	loc = new_location();
	TAILQ_INSERT_TAIL(&host->locations, loc, locations);
}

void
advance_proxy(void)
{
	proxy = new_proxy();
	TAILQ_INSERT_TAIL(&host->proxies, proxy, proxies);
}

int
fastcgi_conf(const char *path, const char *port)
{
	struct fcgi	*f;
	int		i = 0;

	TAILQ_FOREACH(f, &conf->fcgi, fcgi) {
		if (!strcmp(f->path, path) &&
		    ((port == NULL && *f->port == '\0') ||
		     !strcmp(f->port, port)))
			return i;
		++i;
	}

	f = xcalloc(1, sizeof(*f));
	f->id = i;
	if (strlcpy(f->path, path, sizeof(f->path)) >= sizeof(f->path))
		yyerror("fastcgi path is too long: %s", path);
	if (port != NULL &&
	    strlcpy(f->port, port, sizeof(f->port)) >= sizeof(f->port))
		yyerror("port too long: %s", port);
	TAILQ_INSERT_TAIL(&conf->fcgi, f, fcgi);

	return f->id;
}

void
add_param(char *name, char *val)
{
	struct envlist *e;
	struct envhead *h = &loc->params;

	e = xcalloc(1, sizeof(*e));
	if (strlcpy(e->name, name, sizeof(e->name)) >= sizeof(e->name))
		yyerror("parameter name too long: %s", name);
	if (strlcpy(e->value, val, sizeof(e->value)) >= sizeof(e->value))
		yyerror("param value too long: %s", val);
	TAILQ_INSERT_TAIL(h, e, envs);
}

int
getservice(const char *n)
{
	struct servent	*s;
	const char	*errstr;
	long long	 llval;

	llval = strtonum(n, 0, UINT16_MAX, &errstr);
	if (errstr) {
		s = getservbyname(n, "tcp");
		if (s == NULL)
			s = getservbyname(n, "udp");
		if (s == NULL)
			return (-1);
		return (ntohs(s->s_port));
	}

	return ((unsigned short)llval);
}

static void
add_to_addr_queue(struct addrhead *a, struct addrinfo *ai, const char *pp,
    int proxy)
{
	struct address		*addr;
	struct sockaddr_in	*sin;
	struct sockaddr_in6	*sin6;

	if (ai->ai_addrlen > sizeof(addr->ss))
		fatalx("ai_addrlen larger than a sockaddr_storage");

	TAILQ_FOREACH(addr, a, addrs) {
		if (addr->ai_flags == ai->ai_flags &&
		    addr->ai_family == ai->ai_family &&
		    addr->ai_socktype == ai->ai_socktype &&
		    addr->ai_protocol == ai->ai_protocol &&
		    addr->slen == ai->ai_addrlen &&
		    !memcmp(&addr->ss, ai->ai_addr, addr->slen)) {
			if (addr->proxy != proxy)
				yyerror("can't specify the same listen"
				    " address both with and without"
				    " `proxy-v1'.");
			return;
		}
	}

	addr = xcalloc(1, sizeof(*addr));
	addr->ai_flags = ai->ai_flags;
	addr->ai_family = ai->ai_family;
	addr->ai_socktype = ai->ai_socktype;
	addr->ai_protocol = ai->ai_protocol;
	addr->slen = ai->ai_addrlen;
	memcpy(&addr->ss, ai->ai_addr, ai->ai_addrlen);
	strlcpy(addr->pp, pp, sizeof(addr->pp));
	addr->proxy = proxy;

	/* for commodity */
	switch (addr->ai_family) {
	case AF_INET:
		sin = (struct sockaddr_in *)&addr->ss;
		addr->port = ntohs(sin->sin_port);
		break;
	case AF_INET6:
		sin6 = (struct sockaddr_in6 *)&addr->ss;
		addr->port = ntohs(sin6->sin6_port);
		break;
	default:
		fatalx("unknown socket family %d", addr->ai_family);
	}

	addr->sock = -1;

	TAILQ_INSERT_HEAD(a, addr, addrs);
}

void
listen_on(const char *hostname, const char *servname, int proxy)
{
	struct addrinfo hints, *res, *res0;
	char pp[NI_MAXHOST];
	int error;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	error = getaddrinfo(hostname, servname, &hints, &res0);
	if (error) {
		yyerror("listen on \"%s\" port %s: %s", hostname, servname,
		    gai_strerror(errno));
		return;
	}

	for (res = res0; res; res = res->ai_next) {
		if (getnameinfo(res->ai_addr, res->ai_addrlen, pp, sizeof(pp),
		    NULL, 0, NI_NUMERICHOST) == -1) {
			yyerror("getnameinfo failed: %s", strerror(errno));
			break;
		}

		add_to_addr_queue(&host->addrs, res, pp, proxy);
		add_to_addr_queue(&conf->addrs, res, pp, proxy);
	}

	freeaddrinfo(res0);
}
#line 1552 "y.tab.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
static int yygrowstack(void)
{
    unsigned int newsize;
    long sslen;
    short *newss;
    YYSTYPE *newvs;

    if ((newsize = yystacksize) == 0)
        newsize = YYINITSTACKSIZE;
    else if (newsize >= YYMAXDEPTH)
        return -1;
    else if ((newsize *= 2) > YYMAXDEPTH)
        newsize = YYMAXDEPTH;
    sslen = yyssp - yyss;
#ifdef SIZE_MAX
#define YY_SIZE_MAX SIZE_MAX
#else
#define YY_SIZE_MAX 0xffffffffU
#endif
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
        goto bail;
    newss = (short *)realloc(yyss, newsize * sizeof *newss);
    if (newss == NULL)
        goto bail;
    yyss = newss;
    yyssp = newss + sslen;
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
        goto bail;
    newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
    if (newvs == NULL)
        goto bail;
    yyvs = newvs;
    yyvsp = newvs + sslen;
    yystacksize = newsize;
    yysslim = yyss + newsize - 1;
    return 0;
bail:
    if (yyss)
            free(yyss);
    if (yyvs)
            free(yyvs);
    yyss = yyssp = NULL;
    yyvs = yyvsp = NULL;
    yystacksize = 0;
    return -1;
}

#define YYABORT goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
int
yyparse(void)
{
    int yym, yyn, yystate;
#if YYDEBUG
    const char *yys;

    if ((yys = getenv("YYDEBUG")))
    {
        yyn = *yys;
        if (yyn >= '0' && yyn <= '9')
            yydebug = yyn - '0';
    }
#endif /* YYDEBUG */

    yynerrs = 0;
    yyerrflag = 0;
    yychar = (-1);

    if (yyss == NULL && yygrowstack()) goto yyoverflow;
    yyssp = yyss;
    yyvsp = yyvs;
    *yyssp = yystate = 0;

yyloop:
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
    if (yychar < 0)
    {
        if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("%sdebug: state %d, reading %d (%s)\n",
                    YYPREFIX, yystate, yychar, yys);
        }
#endif
    }
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
#if YYDEBUG
        if (yydebug)
            printf("%sdebug: state %d, shifting to state %d\n",
                    YYPREFIX, yystate, yytable[yyn]);
#endif
        if (yyssp >= yysslim && yygrowstack())
        {
            goto yyoverflow;
        }
        *++yyssp = yystate = yytable[yyn];
        *++yyvsp = yylval;
        yychar = (-1);
        if (yyerrflag > 0)  --yyerrflag;
        goto yyloop;
    }
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
        yyn = yytable[yyn];
        goto yyreduce;
    }
    if (yyerrflag) goto yyinrecovery;
#if defined(__GNUC__)
    goto yynewerror;
#endif
yynewerror:
    yyerror("syntax error");
#if defined(__GNUC__)
    goto yyerrlab;
#endif
yyerrlab:
    ++yynerrs;
yyinrecovery:
    if (yyerrflag < 3)
    {
        yyerrflag = 3;
        for (;;)
        {
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
            {
#if YYDEBUG
                if (yydebug)
                    printf("%sdebug: state %d, error recovery shifting\
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
#endif
                if (yyssp >= yysslim && yygrowstack())
                {
                    goto yyoverflow;
                }
                *++yyssp = yystate = yytable[yyn];
                *++yyvsp = yylval;
                goto yyloop;
            }
            else
            {
#if YYDEBUG
                if (yydebug)
                    printf("%sdebug: error recovery discarding state %d\n",
                            YYPREFIX, *yyssp);
#endif
                if (yyssp <= yyss) goto yyabort;
                --yyssp;
                --yyvsp;
            }
        }
    }
    else
    {
        if (yychar == 0) goto yyabort;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
                    YYPREFIX, yystate, yychar, yys);
        }
#endif
        yychar = (-1);
        goto yyloop;
    }
yyreduce:
#if YYDEBUG
    if (yydebug)
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
                YYPREFIX, yystate, yyn, yyrule[yyn]);
#endif
    yym = yylen[yyn];
    if (yym)
        yyval = yyvsp[1-yym];
    else
        memset(&yyval, 0, sizeof yyval);
    switch (yyn)
    {
case 9:
#line 162 "parse.y"
{ file->errors++; }
break;
case 10:
#line 165 "parse.y"
{
			struct file	*nfile;

			if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL) {
				yyerror("failed to include file %s", yyvsp[0].v.string);
				free(yyvsp[0].v.string);
				YYERROR;
			}
			free(yyvsp[0].v.string);

			file = nfile;
			lungetc('\n');
		}
break;
case 11:
#line 180 "parse.y"
{ yyval.v.number = 1; }
break;
case 12:
#line 181 "parse.y"
{ yyval.v.number = 0; }
break;
case 13:
#line 184 "parse.y"
{
			if (asprintf(&yyval.v.string, "%s%s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
				free(yyvsp[-1].v.string);
				free(yyvsp[0].v.string);
				yyerror("string: asprintf: %s", strerror(errno));
				YYERROR;
			}
			free(yyvsp[-1].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 15:
#line 197 "parse.y"
{
			char *s;
			if (asprintf(&s, "%d", yyvsp[0].v.number) == -1) {
				yyerror("asprintf: number");
				YYERROR;
			}
			yyval.v.string = s;
		}
break;
case 17:
#line 208 "parse.y"
{
			char *s = yyvsp[-2].v.string;
			while (*s++) {
				if (isspace((unsigned char)*s)) {
					yyerror("macro name cannot contain "
					    "whitespaces");
					free(yyvsp[-2].v.string);
					free(yyvsp[0].v.string);
					YYERROR;
				}
			}
			symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0);
			free(yyvsp[-2].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 18:
#line 225 "parse.y"
{
			if (strlcpy(conf->chroot, yyvsp[0].v.string, sizeof(conf->chroot)) >=
			    sizeof(conf->chroot))
				yyerror("chroot path too long");
			free(yyvsp[0].v.string);
		}
break;
case 19:
#line 231 "parse.y"
{
			yywarn("option `ipv6' is deprecated,"
			    " please use `listen on'");
			if (yyvsp[0].v.number)
				default_host = NULL;
			else
				default_host = "0.0.0.0";
		}
break;
case 21:
#line 240 "parse.y"
{
			yywarn("option `port' is deprecated,"
			    " please use `listen on'");
			default_port = yyvsp[0].v.number;
		}
break;
case 22:
#line 245 "parse.y"
{ conf->prefork = check_prefork_num(yyvsp[0].v.number); }
break;
case 23:
#line 246 "parse.y"
{
			if (tls_config_parse_protocols(&conf->protos, yyvsp[0].v.string) == -1)
				yyerror("invalid protocols string \"%s\"", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 24:
#line 251 "parse.y"
{
			if (strlcpy(conf->user, yyvsp[0].v.string, sizeof(conf->user)) >=
			    sizeof(conf->user))
				yyerror("user name too long");
			free(yyvsp[0].v.string);
		}
break;
case 29:
#line 267 "parse.y"
{
			free(conf->log_access);
			conf->log_access = yyvsp[0].v.string;
		}
break;
case 30:
#line 271 "parse.y"
{
			if (!strcmp("combined", yyvsp[0].v.string))
				conf->log_format = LOG_FORMAT_COMBINED;
			else if (!strcmp("common", yyvsp[0].v.string))
				conf->log_format = LOG_FORMAT_COMMON;
			else if (!strcmp("condensed", yyvsp[0].v.string))
				conf->log_format = LOG_FORMAT_CONDENSED;
			else if (!strcmp("legacy", yyvsp[0].v.string))
				conf->log_format = LOG_FORMAT_LEGACY;
			else
				yyerror("unknown log style: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 31:
#line 284 "parse.y"
{
			const char *str = yyvsp[0].v.string;

			conf->log_syslog = 1;

			if (!strncasecmp(str, "LOG_", 4))
				str += 4;

			if (!strcasecmp(str, "daemon"))
				conf->log_facility = LOG_DAEMON;
#ifdef LOG_FTP
			else if (!strcasecmp(str, "ftp"))
				conf->log_facility = LOG_FTP;
#endif
			else if (!strcasecmp(str, "local1"))
				conf->log_facility = LOG_LOCAL1;
			else if (!strcasecmp(str, "local2"))
				conf->log_facility = LOG_LOCAL2;
			else if (!strcasecmp(str, "local3"))
				conf->log_facility = LOG_LOCAL3;
			else if (!strcasecmp(str, "local4"))
				conf->log_facility = LOG_LOCAL4;
			else if (!strcasecmp(str, "local5"))
				conf->log_facility = LOG_LOCAL5;
			else if (!strcasecmp(str, "local6"))
				conf->log_facility = LOG_LOCAL6;
			else if (!strcasecmp(str, "local7"))
				conf->log_facility = LOG_LOCAL7;
			else if (!strcasecmp(str, "user"))
				conf->log_facility = LOG_USER;
			else
				yywarn("unknown syslog facility `%s'",
				    yyvsp[0].v.string);

			free(yyvsp[0].v.string);
		}
break;
case 32:
#line 320 "parse.y"
{
			conf->log_syslog = 0;
		}
break;
case 33:
#line 323 "parse.y"
{
			conf->log_syslog = 1;
		}
break;
case 34:
#line 328 "parse.y"
{
			host = new_vhost();
			TAILQ_INSERT_HEAD(&conf->hosts, host, vhosts);

			loc = new_location();
			TAILQ_INSERT_HEAD(&host->locations, loc, locations);

			TAILQ_INIT(&host->proxies);

			(void) strlcpy(loc->match, "*", sizeof(loc->match));

			if (strlcpy(host->domain, yyvsp[0].v.string, sizeof(host->domain))
			    >= sizeof(host->domain))
				yyerror("server name too long: %s", yyvsp[0].v.string);

			if (strstr(yyvsp[0].v.string, "xn--") != NULL) {
				yywarn("\"%s\" looks like punycode: you "
				    "should use the decoded hostname", yyvsp[0].v.string);
			}

			free(yyvsp[0].v.string);
		}
break;
case 35:
#line 349 "parse.y"
{
			if (host->cert_path == NULL ||
			    host->key_path == NULL)
				yyerror("invalid vhost definition: %s",
				    host->domain);
			if (TAILQ_EMPTY(&host->addrs)) {
				char portno[32];
				int r;

				r = snprintf(portno, sizeof(portno), "%d",
				    default_port);
				if (r < 0 || (size_t)r >= sizeof(portno))
					fatal("snprintf");

				yywarn("missing `listen on' in server %s,"
				    " assuming %s port %d", host->domain,
				    default_host ? default_host : "*",
				    default_port);
				listen_on(default_host, portno, 0);
			}
		}
break;
case 36:
#line 370 "parse.y"
{ yyerror("bad server directive"); }
break;
case 41:
#line 379 "parse.y"
{ yyval.v.string = NULL; }
break;
case 43:
#line 383 "parse.y"
{
			struct alist *a;

			a = xcalloc(1, sizeof(*a));
			if (strlcpy(a->alias, yyvsp[0].v.string, sizeof(a->alias))
			    >= sizeof(a->alias))
				yyerror("alias too long: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
			TAILQ_INSERT_TAIL(&host->aliases, a, aliases);
		}
break;
case 44:
#line 393 "parse.y"
{
			ensure_absolute_path(yyvsp[0].v.string);
			free(host->cert_path);
			host->cert_path = yyvsp[0].v.string;
		}
break;
case 45:
#line 398 "parse.y"
{
			free(yyvsp[0].v.string);
			yyerror("`cgi' was removed in gmid 2.0."
			    "  Please use fastcgi or proxy instead.");
		}
break;
case 46:
#line 403 "parse.y"
{
			ensure_absolute_path(yyvsp[0].v.string);
			free(host->key_path);
			host->key_path = yyvsp[0].v.string;
		}
break;
case 47:
#line 408 "parse.y"
{
			ensure_absolute_path(yyvsp[0].v.string);
			free(host->ocsp_path);
			host->ocsp_path = yyvsp[0].v.string;
		}
break;
case 48:
#line 413 "parse.y"
{
			yywarn("the top-level `param' directive is deprecated."
			    "  Please use `fastcgi { param ... }`");
			add_param(yyvsp[-2].v.string, yyvsp[0].v.string);
		}
break;
case 49:
#line 418 "parse.y"
{
			listen_on(yyvsp[0].v.string, "1965", 0);
			free(yyvsp[0].v.string);
		}
break;
case 50:
#line 422 "parse.y"
{
			listen_on(yyvsp[-2].v.string, yyvsp[0].v.string, 0);
			free(yyvsp[-2].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 51:
#line 427 "parse.y"
{
			char portno[32];
			int r;

			r = snprintf(portno, sizeof(portno), "%d", yyvsp[0].v.number);
			if (r < 0 || (size_t)r >= sizeof(portno))
				fatal("snprintf");

			listen_on(yyvsp[-2].v.string, portno, 0);
			free(yyvsp[-2].v.string);
		}
break;
case 52:
#line 438 "parse.y"
{
			listen_on(yyvsp[-1].v.string, "1965", 1);
			free(yyvsp[-1].v.string);
		}
break;
case 53:
#line 442 "parse.y"
{
			listen_on(yyvsp[-3].v.string, yyvsp[-1].v.string, 1);
			free(yyvsp[-3].v.string);
			free(yyvsp[-1].v.string);
		}
break;
case 54:
#line 447 "parse.y"
{
			char portno[32];
			int r;

			r = snprintf(portno, sizeof(portno), "%d", yyvsp[-1].v.number);
			if (r < 0 || (size_t)r >= sizeof(portno))
				fatal("snprintf");

			listen_on(yyvsp[-3].v.string, portno, 1);
			free(yyvsp[-3].v.string);
		}
break;
case 56:
#line 461 "parse.y"
{ advance_proxy(); }
break;
case 57:
#line 462 "parse.y"
{
			if (*proxy->host == '\0')
				yyerror("invalid proxy block: missing `relay-to' option");

			if ((proxy->cert_path == NULL && proxy->key_path != NULL) ||
			    (proxy->cert_path != NULL && proxy->key_path == NULL))
				yyerror("invalid proxy block: missing cert or key");
		}
break;
case 60:
#line 476 "parse.y"
{ yyval.v.number = 1965; }
break;
case 61:
#line 477 "parse.y"
{
			if ((yyval.v.number = getservice(yyvsp[0].v.string)) == -1)
				yyerror("invalid port number %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 62:
#line 482 "parse.y"
{ yyval.v.number = yyvsp[0].v.number; }
break;
case 63:
#line 485 "parse.y"
{
			if (strlcpy(proxy->match_proto, yyvsp[0].v.string,
			    sizeof(proxy->match_proto))
			    >= sizeof(proxy->match_proto))
				yyerror("proto too long: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 64:
#line 492 "parse.y"
{
			if (strlcpy(proxy->match_host, yyvsp[-1].v.string,
			    sizeof(proxy->match_host))
			    >= sizeof(proxy->match_host))
				yyerror("for-host too long: %s", yyvsp[-1].v.string);
			(void) snprintf(proxy->match_port, sizeof(proxy->match_port),
			    "%d", yyvsp[0].v.number);
			free(yyvsp[-1].v.string);
		}
break;
case 67:
#line 507 "parse.y"
{
			free(proxy->cert);
			ensure_absolute_path(yyvsp[0].v.string);
			proxy->cert_path = yyvsp[0].v.string;
		}
break;
case 68:
#line 512 "parse.y"
{
			free(proxy->key);
			ensure_absolute_path(yyvsp[0].v.string);
			proxy->key_path = yyvsp[0].v.string;
		}
break;
case 69:
#line 517 "parse.y"
{
			if (tls_config_parse_protocols(&proxy->protocols, yyvsp[0].v.string) == -1)
				yyerror("invalid protocols string \"%s\"", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 70:
#line 522 "parse.y"
{
			proxy->proxy = 1;
		}
break;
case 71:
#line 525 "parse.y"
{
			if (strlcpy(proxy->host, yyvsp[-1].v.string, sizeof(proxy->host))
			    >= sizeof(proxy->host))
				yyerror("relay-to host too long: %s", yyvsp[-1].v.string);
			(void) snprintf(proxy->port, sizeof(proxy->port),
			    "%d", yyvsp[0].v.number);
			free(yyvsp[-1].v.string);
		}
break;
case 72:
#line 533 "parse.y"
{
			ensure_absolute_path(yyvsp[0].v.string);
			proxy->reqca_path = yyvsp[0].v.string;
		}
break;
case 73:
#line 537 "parse.y"
{
			if (strlcpy(proxy->sni, yyvsp[0].v.string, sizeof(proxy->sni))
			    >= sizeof(proxy->sni))
				yyerror("sni hostname too long: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 74:
#line 543 "parse.y"
{
			proxy->notls = !yyvsp[0].v.number;
		}
break;
case 75:
#line 546 "parse.y"
{
			proxy->noverifyname = !yyvsp[0].v.number;
		}
break;
case 76:
#line 551 "parse.y"
{ advance_loc(); }
break;
case 77:
#line 551 "parse.y"
{
			/* drop the starting '/' if any */
			if (*yyvsp[-4].v.string == '/')
				memmove(yyvsp[-4].v.string, yyvsp[-4].v.string+1, strlen(yyvsp[-4].v.string));
			if (strlcpy(loc->match, yyvsp[-4].v.string, sizeof(loc->match))
			    >= sizeof(loc->match))
				yyerror("location path too long: %s", yyvsp[-4].v.string);
			free(yyvsp[-4].v.string);
		}
break;
case 81:
#line 567 "parse.y"
{ loc->auto_index = yyvsp[0].v.number ? 1 : -1; }
break;
case 82:
#line 568 "parse.y"
{
			check_block_fmt(yyvsp[0].v.string);
			if (strlcpy(loc->block_fmt, yyvsp[0].v.string, sizeof(loc->block_fmt))
			    >= sizeof(loc->block_fmt))
				yyerror("block return meta too long: %s", yyvsp[0].v.string);
			loc->block_code = check_block_code(yyvsp[-1].v.number);
			free(yyvsp[0].v.string);
		}
break;
case 83:
#line 576 "parse.y"
{
			(void) strlcpy(loc->block_fmt, "temporary failure",
			    sizeof(loc->block_fmt));
			loc->block_code = check_block_code(yyvsp[0].v.number);
			if (yyvsp[0].v.number >= 30 && yyvsp[0].v.number < 40)
				yyerror("missing `meta' for block return %d", yyvsp[0].v.number);
		}
break;
case 84:
#line 583 "parse.y"
{
			(void) strlcpy(loc->block_fmt, "temporary failure",
			    sizeof(loc->block_fmt));
			loc->block_code = 40;
		}
break;
case 85:
#line 588 "parse.y"
{
			if (strlcpy(loc->default_mime, yyvsp[0].v.string,
			    sizeof(loc->default_mime))
			    >= sizeof(loc->default_mime))
				yyerror("default type too long: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 87:
#line 596 "parse.y"
{
			if (strlcpy(loc->index, yyvsp[0].v.string, sizeof(loc->index))
			    >= sizeof(loc->index))
				yyerror("index string too long: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 88:
#line 602 "parse.y"
{
			if (strlcpy(loc->lang, yyvsp[0].v.string, sizeof(loc->lang))
			    >= sizeof(loc->lang))
				yyerror("lang too long: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 89:
#line 608 "parse.y"
{ loc->disable_log = !yyvsp[0].v.number; }
break;
case 90:
#line 609 "parse.y"
{
			ensure_absolute_path(yyvsp[0].v.string);
			loc->reqca_path = yyvsp[0].v.string;
		}
break;
case 91:
#line 613 "parse.y"
{
			if (strlcpy(loc->dir, yyvsp[0].v.string, sizeof(loc->dir))
			    >= sizeof(loc->dir))
				yyerror("root path too long: %s", yyvsp[0].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 92:
#line 619 "parse.y"
{ loc->strip = check_strip_no(yyvsp[0].v.number); }
break;
case 95:
#line 624 "parse.y"
{
			loc->fcgi = -1;
			loc->nofcgi = 1;
		}
break;
case 96:
#line 628 "parse.y"
{
			yywarn("`fastcgi path' is deprecated.  "
			    "Please use `fastcgi socket path' instead.");
			loc->fcgi = fastcgi_conf(yyvsp[0].v.string, NULL);
			free(yyvsp[0].v.string);
		}
break;
case 99:
#line 640 "parse.y"
{
			add_param(yyvsp[-2].v.string, yyvsp[0].v.string);
		}
break;
case 100:
#line 643 "parse.y"
{
			loc->fcgi = fastcgi_conf(yyvsp[0].v.string, NULL);
			free(yyvsp[0].v.string);
		}
break;
case 101:
#line 647 "parse.y"
{
			char *c;

			if (asprintf(&c, "%d", yyvsp[0].v.number) == -1)
				fatal("asprintf");
			loc->fcgi = fastcgi_conf(yyvsp[-2].v.string, c);
			free(yyvsp[-2].v.string);
			free(c);
		}
break;
case 102:
#line 656 "parse.y"
{
			loc->fcgi = fastcgi_conf(yyvsp[0].v.string, "9000");
		}
break;
case 103:
#line 659 "parse.y"
{
			loc->fcgi = fastcgi_conf(yyvsp[-2].v.string, yyvsp[0].v.string);
			free(yyvsp[-2].v.string);
			free(yyvsp[0].v.string);
		}
break;
case 104:
#line 664 "parse.y"
{
			loc->fcgi_strip = yyvsp[0].v.number;
		}
break;
case 108:
#line 675 "parse.y"
{
			free(current_media);
			current_media = yyvsp[0].v.string;
		}
break;
case 113:
#line 686 "parse.y"
{
			if (add_mime(&conf->mime, current_media, yyvsp[0].v.string) == -1)
				fatal("add_mime");
			free(yyvsp[0].v.string);
		}
break;
#line 2404 "y.tab.c"
    }
    yyssp -= yym;
    yystate = *yyssp;
    yyvsp -= yym;
    yym = yylhs[yyn];
    if (yystate == 0 && yym == 0)
    {
#if YYDEBUG
        if (yydebug)
            printf("%sdebug: after reduction, shifting from state 0 to\
 state %d\n", YYPREFIX, YYFINAL);
#endif
        yystate = YYFINAL;
        *++yyssp = YYFINAL;
        *++yyvsp = yyval;
        if (yychar < 0)
        {
            if ((yychar = yylex()) < 0) yychar = 0;
#if YYDEBUG
            if (yydebug)
            {
                yys = 0;
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                if (!yys) yys = "illegal-symbol";
                printf("%sdebug: state %d, reading %d (%s)\n",
                        YYPREFIX, YYFINAL, yychar, yys);
            }
#endif
        }
        if (yychar == 0) goto yyaccept;
        goto yyloop;
    }
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
        yystate = yytable[yyn];
    else
        yystate = yydgoto[yym];
#if YYDEBUG
    if (yydebug)
        printf("%sdebug: after reduction, shifting from state %d \
to state %d\n", YYPREFIX, *yyssp, yystate);
#endif
    if (yyssp >= yysslim && yygrowstack())
    {
        goto yyoverflow;
    }
    *++yyssp = yystate;
    *++yyvsp = yyval;
    goto yyloop;
yyoverflow:
    yyerror("yacc stack overflow");
yyabort:
    if (yyss)
            free(yyss);
    if (yyvs)
            free(yyvs);
    yyss = yyssp = NULL;
    yyvs = yyvsp = NULL;
    yystacksize = 0;
    return (1);
yyaccept:
    if (yyss)
            free(yyss);
    if (yyvs)
            free(yyvs);
    yyss = yyssp = NULL;
    yyvs = yyvsp = NULL;
    yystacksize = 0;
    return (0);
}
