#ifndef lint
/*static char yysccsid[] = "from: @(#)yaccpar	1.9 (Berkeley) 02/21/93";*/
static char yyrcsid[]
#if __GNUC__ >= 2
  __attribute__ ((unused))
#endif /* __GNUC__ >= 2 */
  = "$OpenBSD: skeleton.c,v 1.24 2005/06/10 16:40:45 pvalchev Exp $";
#endif
#include <stdlib.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 33 "parse.y"
#include <sys/types.h>

#include "config.h"

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <sys/tree.h>
#include <sys/queue.h>

#define _XOPEN_SOURCE /* glibc2 is stupid and needs this */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#include <pcap.h>
#include <dnet.h>

#include <event.h>

#include "honeyd.h"
#include "personality.h"
#include "router.h"
#include "plugins_config.h"
#include "plugins.h"
#include "template.h"
#include "condition.h"
#include "interface.h"
#include "ethernet.h"
#include "pfvar.h"
#include "dhcpclient.h"
#include "subsystem.h"
#include "util.h"
#ifdef HAVE_PYTHON
#include "pyextend.h"
#endif

int hydlex(void);
int hydparse(void);
int hyderror(char *, ...);
int hydwarn(char *, ...);
int hydprintf(char *, ...);
void *hyd_scan_string(char *);
int hyd_delete_buffer(void *);

#define yylex hydlex
#define yyparse hydparse
#define yy_scan_string hyd_scan_string
#define yy_delete_buffer hyd_delete_buffer
#define yyerror hyderror
#define yywarn hydwarn
#define yyprintf hydprintf
#define yyin hydin

extern int honeyd_verify_config;

pf_osfp_t pfctl_get_fingerprint(const char *);
struct action *honeyd_protocol(struct template *, int);
void port_action_clone(struct action *, struct action *);
static void dhcp_template(struct template *tmpl,
    char *interface, char *mac_addr);

static struct evbuffer *buffer = NULL;
int lineno;
char *filename;
int errors = 0;
int curtype = -1;	/* Lex sets it to SOCK_STREAM or _DGRAM */

#line 141 "parse.y"
#ifndef YYSTYPE_DEFINED
#define YYSTYPE_DEFINED
typedef union {
	char *string;
	int number;
	struct link_drop drop;
	struct addr addr;
	struct action action;
	struct template *tmpl;
	struct personality *pers;
	struct addrinfo *ai;
	enum fragpolicy fragp;
	float floatp;
	struct condition condition;
	struct tm time;
	struct condition_time timecondition;
} YYSTYPE;
#endif /* YYSTYPE_DEFINED */
#line 113 "parse.c"
#define CREATE 257
#define ADD 258
#define PORT 259
#define BIND 260
#define CLONE 261
#define DOT 262
#define BLOCK 263
#define OPEN 264
#define RESET 265
#define DEFAULT 266
#define SET 267
#define ACTION 268
#define PERSONALITY 269
#define RANDOM 270
#define ANNOTATE 271
#define NO 272
#define FINSCAN 273
#define FRAGMENT 274
#define DROP 275
#define OLD 276
#define NEW 277
#define COLON 278
#define PROXY 279
#define UPTIME 280
#define DROPRATE 281
#define IN 282
#define SYN 283
#define UID 284
#define GID 285
#define ROUTE 286
#define ENTRY 287
#define LINK 288
#define NET 289
#define UNREACH 290
#define SLASH 291
#define LATENCY 292
#define MS 293
#define LOSS 294
#define BANDWIDTH 295
#define SUBSYSTEM 296
#define OPTION 297
#define TO 298
#define SHARED 299
#define NETWORK 300
#define SPOOF 301
#define FROM 302
#define TEMPLATE 303
#define TUNNEL 304
#define TARPIT 305
#define DYNAMIC 306
#define USE 307
#define IF 308
#define OTHERWISE 309
#define EQUAL 310
#define SOURCE 311
#define OS 312
#define IP 313
#define BETWEEN 314
#define DELETE 315
#define LIST 316
#define ETHERNET 317
#define DHCP 318
#define ON 319
#define MAXFDS 320
#define RESTART 321
#define DEBUG 322
#define DASH 323
#define TIME 324
#define INTERNAL 325
#define STRING 326
#define CMDSTRING 327
#define IPSTRING 328
#define NUMBER 329
#define PROTO 330
#define FLOAT 331
#define YYERRCODE 256
#if defined(__cplusplus) || defined(__STDC__)
const short yylhs[] =
#else
short yylhs[] =
#endif
	{                                        -1,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,   20,   20,   20,   20,   22,   22,   21,   21,   21,
   23,   24,   24,   24,   24,   24,   24,   24,   24,   24,
   25,   25,   25,   25,   25,   25,   25,   25,   25,   26,
   26,   27,   27,   27,   27,   27,   27,    7,    7,    8,
    8,    8,    1,    1,    2,    3,    4,    4,    4,    4,
    4,    4,    4,    4,    4,    5,    5,    5,    5,    6,
    6,    9,    9,   11,   11,   13,   13,   12,   12,   12,
   10,   10,   28,   28,   28,   28,   29,   29,   29,   29,
   29,   29,   29,   14,   14,   15,   15,   16,   16,   17,
   17,   17,   17,   17,   17,   18,   19,   19,
};
#if defined(__cplusplus) || defined(__STDC__)
const short yylen[] =
#else
short yylen[] =
#endif
	{                                         2,
    0,    2,    2,    2,    2,    2,    2,    2,    2,    2,
    2,    2,    2,    2,    2,    2,    5,    6,    6,    5,
    6,    3,    4,    4,    4,    6,    3,    5,    5,    7,
    6,    4,    4,    4,    5,    5,    4,    4,    6,    3,
    3,    3,    5,   10,    8,    4,    4,    1,    2,    2,
    2,    2,    1,    1,    3,    3,    2,    2,    3,    3,
    5,    5,    1,    1,    2,    1,    1,    1,    1,    1,
    1,    1,    1,    0,    3,    0,    2,    0,    3,    2,
    0,    7,    4,    4,    4,    5,    2,    3,    3,    2,
    3,    3,    3,    0,    1,    0,    1,    0,    1,    4,
    4,    4,    2,    1,    1,    4,    4,    1,
};
#if defined(__cplusplus) || defined(__STDC__)
const short yydefred[] =
#else
short yydefred[] =
#endif
	{                                      1,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    2,    3,    4,    5,    6,    7,
    8,    9,   10,   11,   14,   13,   12,   68,   67,   66,
   54,   53,   69,    0,  105,    0,    0,  104,    0,    0,
    0,    0,   71,   70,    0,    0,    0,    0,   15,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,  103,    0,   22,    0,   27,    0,    0,    0,    0,
    0,    0,    0,    0,    0,   48,    0,   40,   41,    0,
    0,    0,    0,    0,    0,   91,   92,   89,   88,    0,
   93,    0,    0,    0,    0,    0,    0,  108,    0,    0,
   24,   23,    0,   32,   34,    0,    0,    0,    0,    0,
   33,   37,   49,   50,   51,   52,    0,    0,    0,   46,
   47,    0,   85,   83,   84,    0,    0,   95,    0,    0,
   20,    0,  100,    0,  102,    0,    0,    0,   73,   72,
   35,   36,    0,   29,    0,   43,    0,    0,   86,   17,
    0,   97,   21,   19,   63,   64,   99,   18,    0,    0,
  106,   31,   39,    0,    0,    0,   55,   26,   65,    0,
    0,   57,   58,  107,   30,    0,    0,    0,    0,    0,
   60,   59,   45,    0,    0,    0,    0,    0,   75,   77,
    0,    0,   62,   61,   56,    0,    0,   44,   79,    0,
    0,    0,    0,    0,   82,
};
#if defined(__cplusplus) || defined(__STDC__)
const short yydgoto[] =
#else
short yydgoto[] =
#endif
	{                                       1,
   33,  120,  181,  158,   34,   45,   78,   79,  141,  198,
  178,  192,  186,  129,  153,  159,   40,   62,  100,   15,
   16,   17,   18,   19,   20,   21,   22,   23,   24,
};
#if defined(__cplusplus) || defined(__STDC__)
const short yysindex[] =
#else
short yysindex[] =
#endif
	{                                      0,
 -245, -258, -229, -197, -315, -229, -251, -273, -309, -297,
 -229, -276, -229, -290,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0, -196,    0, -184, -271,    0, -236, -202,
 -229, -163,    0,    0, -216, -202, -248, -280,    0, -270,
 -183, -180, -250, -257, -234, -229, -175, -154, -190, -168,
 -233,    0, -203,    0, -229,    0, -178, -251, -179, -134,
 -176, -219, -172, -173, -115,    0, -140,    0,    0, -141,
 -129, -202, -202, -207,  -98,    0,    0,    0,    0, -162,
    0, -133, -143, -229, -160, -157, -202,    0, -111, -152,
    0,    0,  -96,    0,    0, -227, -227, -110, -202, -202,
    0,    0,    0,    0,    0,    0, -202, -202, -114,    0,
    0, -150,    0,    0,    0, -149, -138,    0, -139, -277,
    0, -242,    0, -114,    0, -148, -233, -242,    0,    0,
    0,    0, -146,    0, -113,    0, -279, -145,    0,    0,
 -137,    0,    0,    0,    0,    0,    0,    0, -261, -135,
    0,    0,    0, -202, -202, -106,    0,    0,    0, -187,
 -132,    0,    0,    0,    0, -202, -142, -105,  -90,  -86,
    0,    0,    0, -100, -227, -101, -298, -131,    0,    0,
 -130,  -79,    0,    0,    0, -128, -117,    0,    0, -127,
  -93, -120, -125,  -88,    0,};
#if defined(__cplusplus) || defined(__STDC__)
const short yyrindex[] =
#else
short yyrindex[] =
#endif
	{                                      0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,  173,
  178,  241,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,  246,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,   78,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,  263,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,  313,    0,  330,    0,
    0, -240,    0,    1,    0,    0,    0, -240,    0,    0,
    0,    0,    0,    0,  347,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,   51,    0,    0,
    0,    0,    0,    0,    0,  101,    0,    0,    0,    0,
    0,  380,    0,    0,    0,  151,    0,    0,    0,    0,
    0,    0,    0,    0,    0,};
#if defined(__cplusplus) || defined(__STDC__)
const short yygindex[] =
#else
short yygindex[] =
#endif
	{                                      0,
   -2,   -8,    0,   68,   -6,  139,    0,    0, -103,    0,
    0,    0,    0,    0,    0,    0,   79,    0,   71,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,
};
#define YYTABLESIZE 702
#if defined(__cplusplus) || defined(__STDC__)
const short yytable[] =
#else
short yytable[] =
#endif
	{                                      42,
  101,   39,  169,  142,   50,   47,   53,   25,   74,   81,
   41,    2,    3,   46,    4,    5,   48,  170,   43,   51,
  155,    6,  156,   98,  165,    7,   52,  193,   49,   28,
  194,   35,   64,   36,   66,   54,   28,   65,   98,   82,
    8,   83,   61,   80,   26,   84,   37,   31,   32,   93,
   76,    9,   38,   31,   32,   75,   76,   77,  102,   85,
   10,   63,  157,  171,  172,  173,   29,   27,   90,   11,
   12,   91,   13,   29,  121,   44,   14,   94,  109,  119,
  119,  190,  110,  122,   98,   98,   98,  131,  135,   30,
   31,   32,   92,   98,  134,   99,   30,   31,   32,   55,
   78,  139,   67,  140,   95,   68,  144,  145,  146,  147,
   56,   35,   57,   36,  119,  119,   69,   70,  123,   96,
   71,  124,  101,  125,   31,   32,   37,   59,   60,   31,
   32,   94,   38,   58,  114,  115,  116,   72,  179,   31,
   32,   97,   86,   87,  166,   88,   89,  106,  107,  105,
   80,  103,  108,   73,  111,  112,   74,  113,  117,  118,
  126,  175,  176,  127,  130,  128,  136,  180,  132,  133,
  137,  138,   16,  183,  143,  149,  148,   90,  151,  150,
  160,  152,  163,  167,  164,  177,  184,  187,  185,  168,
  174,  188,  189,  191,  182,  197,  200,  195,  196,  202,
  199,  201,  203,  204,  205,  162,  104,  161,  154,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
   87,    0,    0,    0,    0,   42,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,  101,  101,    0,
  101,  101,   38,    0,    0,   74,   74,  101,   74,   74,
    0,  101,    0,    0,    0,   74,    0,    0,    0,   74,
    0,    0,    0,   74,    0,    0,  101,    0,    0,    0,
    0,    0,    0,    0,   74,    0,    0,  101,    0,    0,
    0,    0,   74,   74,    0,   74,  101,   76,   76,    0,
   76,   76,   25,    0,   74,  101,  101,   76,  101,    0,
    0,   76,  101,   74,   74,   76,   74,  101,  101,   96,
   74,    0,    0,    0,   94,   94,   76,   94,   94,    0,
    0,    0,    0,    0,   94,   76,   28,   76,   94,    0,
    0,    0,    0,    0,    0,    0,   76,   78,   78,    0,
   78,   78,    0,   94,    0,   76,   76,   78,   76,    0,
    0,   78,   76,    0,   94,   78,    0,    0,    0,   81,
    0,    0,    0,   94,    0,    0,   78,    0,    0,    0,
    0,    0,   94,   94,    0,   94,    0,   78,   94,   94,
    0,    0,    0,    0,    0,    0,   78,   80,   80,    0,
   80,   80,    0,    0,    0,   78,   78,   80,   78,    0,
    0,   80,   78,    0,    0,   80,    0,    0,    0,   16,
   16,    0,   16,   16,   90,   90,   80,   90,   90,   16,
    0,    0,    0,   16,   90,    0,    0,   80,   90,    0,
    0,    0,    0,    0,    0,    0,   80,    0,   16,    0,
    0,    0,    0,   90,    0,   80,   80,    0,   80,   16,
    0,    0,   80,    0,   90,    0,    0,    0,   16,    0,
    0,    0,    0,   90,    0,    0,    0,   16,   16,    0,
   16,    0,   90,   90,   16,   90,    0,   87,   87,   90,
   87,   87,   42,   42,    0,   42,   42,   87,    0,    0,
    0,   87,   42,    0,    0,    0,   42,    0,    0,   38,
   38,    0,   38,   38,    0,    0,   87,    0,    0,   38,
    0,   42,    0,   38,    0,    0,    0,   87,    0,    0,
    0,    0,   42,    0,    0,    0,   87,    0,   38,    0,
    0,   42,    0,    0,    0,   87,   87,    0,   87,   38,
   42,   42,   87,   42,    0,    0,    0,   42,   38,   25,
   25,    0,   25,   25,    0,    0,    0,   38,   38,   25,
   38,    0,    0,   25,   38,    0,   96,   96,    0,   96,
   96,    0,    0,    0,    0,    0,   96,    0,   25,    0,
   96,    0,    0,   28,   28,    0,   28,   28,    0,   25,
    0,    0,    0,   28,    0,   96,    0,   28,   25,    0,
    0,    0,    0,    0,    0,    0,   96,   25,   25,    0,
   25,    0,   28,    0,   25,   96,   81,   81,    0,   81,
   81,    0,    0,   28,   96,   96,   81,   96,    0,    0,
   81,   96,   28,    0,    0,    0,    0,    0,    0,    0,
    0,   28,   28,    0,   28,   81,    0,    0,   28,    0,
    0,    0,    0,    0,    0,    0,   81,    0,    0,    0,
    0,    0,    0,    0,    0,   81,    0,    0,    0,    0,
    0,    0,    0,    0,   81,   81,    0,   81,    0,    0,
    0,   81,
};
#if defined(__cplusplus) || defined(__STDC__)
const short yycheck[] =
#else
short yycheck[] =
#endif
	{                                       6,
    0,    4,  264,  107,   11,    8,   13,  266,    0,  258,
  326,  257,  258,  287,  260,  261,  326,  279,  270,  296,
  263,  267,  265,  264,  304,  271,  303,  326,  326,  266,
  329,  309,   39,  311,   41,  326,  266,   40,  279,  288,
  286,  290,  314,   46,  303,  326,  324,  327,  328,   56,
    0,  297,  330,  327,  328,  272,  273,  274,   65,  330,
  306,  298,  305,  325,  326,  327,  303,  326,  319,  315,
  316,  329,  318,  303,   83,  327,  322,    0,  298,   82,
   83,  185,  302,  291,  325,  326,  327,   94,   97,  326,
  327,  328,  327,  327,   97,  329,  326,  327,  328,  296,
    0,  329,  266,  331,  259,  269,  109,  110,  117,  118,
  307,  309,  309,  311,  117,  118,  280,  281,  326,  310,
  284,  329,  326,  331,  327,  328,  324,  312,  313,  327,
  328,  307,  330,  330,  275,  276,  277,  301,  326,  327,
  328,  310,  326,  327,  147,  326,  327,  282,  283,  329,
    0,  330,  329,  317,  327,  329,  320,  273,  300,  289,
  259,  164,  165,  326,  308,  299,  278,  170,  329,  327,
  323,  268,    0,  176,  285,  326,  291,    0,  317,  329,
  329,  321,  329,  329,  298,  292,  329,  278,  294,  327,
  326,  278,  293,  295,  327,  275,  314,  329,  329,  293,
  329,  329,  323,  329,  293,  138,   68,  137,  130,   -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,   -1,   -1,   -1,   -1,
    0,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,  257,  258,   -1,
  260,  261,    0,   -1,   -1,  257,  258,  267,  260,  261,
   -1,  271,   -1,   -1,   -1,  267,   -1,   -1,   -1,  271,
   -1,   -1,   -1,  275,   -1,   -1,  286,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,  286,   -1,   -1,  297,   -1,   -1,
   -1,   -1,  294,  295,   -1,  297,  306,  257,  258,   -1,
  260,  261,    0,   -1,  306,  315,  316,  267,  318,   -1,
   -1,  271,  322,  315,  316,  275,  318,  327,  328,    0,
  322,   -1,   -1,   -1,  257,  258,  286,  260,  261,   -1,
   -1,   -1,   -1,   -1,  267,  295,    0,  297,  271,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  306,  257,  258,   -1,
  260,  261,   -1,  286,   -1,  315,  316,  267,  318,   -1,
   -1,  271,  322,   -1,  297,  275,   -1,   -1,   -1,    0,
   -1,   -1,   -1,  306,   -1,   -1,  286,   -1,   -1,   -1,
   -1,   -1,  315,  316,   -1,  318,   -1,  297,  321,  322,
   -1,   -1,   -1,   -1,   -1,   -1,  306,  257,  258,   -1,
  260,  261,   -1,   -1,   -1,  315,  316,  267,  318,   -1,
   -1,  271,  322,   -1,   -1,  275,   -1,   -1,   -1,  257,
  258,   -1,  260,  261,  257,  258,  286,  260,  261,  267,
   -1,   -1,   -1,  271,  267,   -1,   -1,  297,  271,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  306,   -1,  286,   -1,
   -1,   -1,   -1,  286,   -1,  315,  316,   -1,  318,  297,
   -1,   -1,  322,   -1,  297,   -1,   -1,   -1,  306,   -1,
   -1,   -1,   -1,  306,   -1,   -1,   -1,  315,  316,   -1,
  318,   -1,  315,  316,  322,  318,   -1,  257,  258,  322,
  260,  261,  257,  258,   -1,  260,  261,  267,   -1,   -1,
   -1,  271,  267,   -1,   -1,   -1,  271,   -1,   -1,  257,
  258,   -1,  260,  261,   -1,   -1,  286,   -1,   -1,  267,
   -1,  286,   -1,  271,   -1,   -1,   -1,  297,   -1,   -1,
   -1,   -1,  297,   -1,   -1,   -1,  306,   -1,  286,   -1,
   -1,  306,   -1,   -1,   -1,  315,  316,   -1,  318,  297,
  315,  316,  322,  318,   -1,   -1,   -1,  322,  306,  257,
  258,   -1,  260,  261,   -1,   -1,   -1,  315,  316,  267,
  318,   -1,   -1,  271,  322,   -1,  257,  258,   -1,  260,
  261,   -1,   -1,   -1,   -1,   -1,  267,   -1,  286,   -1,
  271,   -1,   -1,  257,  258,   -1,  260,  261,   -1,  297,
   -1,   -1,   -1,  267,   -1,  286,   -1,  271,  306,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  297,  315,  316,   -1,
  318,   -1,  286,   -1,  322,  306,  257,  258,   -1,  260,
  261,   -1,   -1,  297,  315,  316,  267,  318,   -1,   -1,
  271,  322,  306,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,  315,  316,   -1,  318,  286,   -1,   -1,  322,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  297,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,  306,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,  315,  316,   -1,  318,   -1,   -1,
   -1,  322,
};
#define YYFINAL 1
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 331
#if YYDEBUG
#if defined(__cplusplus) || defined(__STDC__)
const char * const yyname[] =
#else
char *yyname[] =
#endif
	{
"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"CREATE","ADD","PORT","BIND",
"CLONE","DOT","BLOCK","OPEN","RESET","DEFAULT","SET","ACTION","PERSONALITY",
"RANDOM","ANNOTATE","NO","FINSCAN","FRAGMENT","DROP","OLD","NEW","COLON",
"PROXY","UPTIME","DROPRATE","IN","SYN","UID","GID","ROUTE","ENTRY","LINK","NET",
"UNREACH","SLASH","LATENCY","MS","LOSS","BANDWIDTH","SUBSYSTEM","OPTION","TO",
"SHARED","NETWORK","SPOOF","FROM","TEMPLATE","TUNNEL","TARPIT","DYNAMIC","USE",
"IF","OTHERWISE","EQUAL","SOURCE","OS","IP","BETWEEN","DELETE","LIST",
"ETHERNET","DHCP","ON","MAXFDS","RESTART","DEBUG","DASH","TIME","INTERNAL",
"STRING","CMDSTRING","IPSTRING","NUMBER","PROTO","FLOAT",
};
#if defined(__cplusplus) || defined(__STDC__)
const char * const yyrule[] =
#else
char *yyrule[] =
#endif
	{"$accept : config",
"config :",
"config : config creation",
"config : config addition",
"config : config delete",
"config : config subsystem",
"config : config binding",
"config : config set",
"config : config annotate",
"config : config route",
"config : config option",
"config : config ui",
"creation : CREATE STRING",
"creation : CREATE TEMPLATE",
"creation : CREATE DEFAULT",
"creation : DYNAMIC STRING",
"delete : DELETE template",
"delete : DELETE template PROTO PORT NUMBER",
"addition : ADD template PROTO PORT NUMBER action",
"addition : ADD template USE template IF condition",
"addition : ADD template OTHERWISE USE template",
"subsystem : ADD template SUBSYSTEM CMDSTRING shared restart",
"binding : BIND ipaddr template",
"binding : BIND condition ipaddr template",
"binding : BIND ipaddr TO STRING",
"binding : DHCP template ON STRING",
"binding : DHCP template ON STRING ETHERNET CMDSTRING",
"binding : CLONE STRING template",
"binding : SET template SPOOF FROM ipaddr",
"binding : SET template SPOOF TO ipaddr",
"binding : SET template SPOOF FROM ipaddr TO ipaddr",
"set : SET template DEFAULT PROTO ACTION action",
"set : SET template PERSONALITY personality",
"set : SET template ETHERNET CMDSTRING",
"set : SET template UPTIME NUMBER",
"set : SET template DROPRATE IN rate",
"set : SET template DROPRATE SYN rate",
"set : SET template MAXFDS NUMBER",
"set : SET template UID NUMBER",
"set : SET template UID NUMBER GID NUMBER",
"annotate : ANNOTATE personality finscan",
"annotate : ANNOTATE personality fragment",
"route : ROUTE ENTRY ipaddr",
"route : ROUTE ENTRY ipaddr NETWORK ipnet",
"route : ROUTE ipaddr ADD NET ipnet ipaddr latency packetloss bandwidth randomearlydrop",
"route : ROUTE ipaddr ADD NET ipnet TUNNEL ipaddr ipaddr",
"route : ROUTE ipaddr LINK ipnet",
"route : ROUTE ipaddr UNREACH ipnet",
"finscan : FINSCAN",
"finscan : NO FINSCAN",
"fragment : FRAGMENT DROP",
"fragment : FRAGMENT OLD",
"fragment : FRAGMENT NEW",
"ipaddr : IPSTRING",
"ipaddr : CMDSTRING",
"ipnet : ipaddr SLASH NUMBER",
"ipaddrplusport : ipaddr COLON NUMBER",
"action : flags STRING",
"action : flags CMDSTRING",
"action : flags INTERNAL CMDSTRING",
"action : flags PROXY ipaddrplusport",
"action : flags PROXY STRING COLON NUMBER",
"action : flags PROXY STRING COLON STRING",
"action : BLOCK",
"action : RESET",
"action : flags OPEN",
"template : STRING",
"template : TEMPLATE",
"template : DEFAULT",
"template : ipaddr",
"personality : CMDSTRING",
"personality : RANDOM",
"rate : FLOAT",
"rate : NUMBER",
"latency :",
"latency : LATENCY NUMBER MS",
"packetloss :",
"packetloss : LOSS rate",
"bandwidth :",
"bandwidth : BANDWIDTH NUMBER NUMBER",
"bandwidth : BANDWIDTH NUMBER",
"randomearlydrop :",
"randomearlydrop : DROP BETWEEN NUMBER MS DASH NUMBER MS",
"option : OPTION STRING STRING NUMBER",
"option : OPTION STRING STRING FLOAT",
"option : OPTION STRING STRING STRING",
"option : OPTION STRING STRING SLASH STRING",
"ui : LIST TEMPLATE",
"ui : LIST TEMPLATE CMDSTRING",
"ui : LIST TEMPLATE STRING",
"ui : LIST SUBSYSTEM",
"ui : LIST SUBSYSTEM STRING",
"ui : LIST SUBSYSTEM CMDSTRING",
"ui : DEBUG STRING NUMBER",
"shared :",
"shared : SHARED",
"restart :",
"restart : RESTART",
"flags :",
"flags : TARPIT",
"condition : SOURCE OS EQUAL CMDSTRING",
"condition : SOURCE IP EQUAL ipaddr",
"condition : SOURCE IP EQUAL ipnet",
"condition : TIME timecondition",
"condition : PROTO",
"condition : OTHERWISE",
"timecondition : BETWEEN time DASH time",
"time : NUMBER COLON NUMBER STRING",
"time : CMDSTRING",
};
#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
int yydebug;
int yynerrs;
int yyerrflag;
int yychar;
short *yyssp;
YYSTYPE *yyvsp;
YYSTYPE yyval;
YYSTYPE yylval;
short *yyss;
short *yysslim;
YYSTYPE *yyvs;
int yystacksize;
#line 1068 "parse.y"

static void
dhcp_template(struct template *tmpl, char *interface, char *mac_addr)
{
	struct interface *inter;
	struct template *newtmpl;
	struct addr addr;
	extern int need_dhcp;
	extern int need_arp;

	if (mac_addr == NULL && tmpl->ethernet_addr == NULL) {
		yyerror("Need an ethernet address for DHCP.");
		return;
	}

	/* Find the right interface */
	if ((inter = interface_find(interface)) == NULL) {
		yyerror("Interface \"%s\" does not exist.", interface);
		return;
	}
	if (inter->if_ent.intf_link_addr.addr_type != ADDR_TYPE_ETH) {
		yyerror("Interface \"%s\" does not support ARP.", interface);
		return;
	}

	/* Need to find a temporary IP address */
	if (template_get_dhcp_address(&addr) == -1) {
		yyerror("Failed to obtain temporary IP address.");
		return;
	}

	newtmpl = template_clone(addr_ntoa(&addr), tmpl, inter, 1);
	if (newtmpl == NULL) {
		yyerror("Binding to %s failed", addr_ntoa(&addr));
		return;
	}

	if (mac_addr != NULL) {
		/*
		 * This is more complicated than it should be.
		 * 1. Remove existing ARP table entries.
		 * 2. Set new ethernet MAC address
		 * 3. Assign interface to template
		 * 4. Post new ARP table entry.
		 */
		template_remove_arp(newtmpl);

		newtmpl->ethernet_addr = ethernetcode_make_address(mac_addr);
		if (newtmpl->ethernet_addr == NULL) {
			yyerror("Unknown ethernet vendor \"%s\"", mac_addr);
		}

		newtmpl->inter = inter;

		/* We need to update the ARP binding */
		template_post_arp(newtmpl, &addr);
	}

	/* We can ignore the rest if we just verify the configuration */
	if (honeyd_verify_config)
		return;

	/* Wow - now we can assign the DHCP object to it */
	if (dhcp_getconf(newtmpl) == -1) {
		yyerror("Failed to start DHCP on %s",
		    inter->if_ent.intf_name);
		return;
	}

	need_arp = need_dhcp = 1;
}

int
yyerror(char *fmt, ...)
{
	va_list ap;
	errors = 1;

	va_start(ap, fmt);
	if (buffer == NULL) {
		fprintf(stderr, "%s:%d: ", filename, lineno);
		vfprintf(stderr, fmt, ap);
		fprintf(stderr, "\n");
	} else {
		char *data;
		if (vasprintf(&data, fmt, ap) == -1)
			err(1, "%s: vasprintf", __func__);
		evbuffer_add_printf(buffer, "%s: %s\n", filename, data);
		free(data);
	}
	va_end(ap);
	return (0);
}

int
yywarn(char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	if (buffer == NULL) {
		fprintf(stderr, "%s:%d: ", filename, lineno);
		vfprintf(stderr, fmt, ap);
		fprintf(stderr, "\n");
	} else {
		char *data;
		if (vasprintf(&data, fmt, ap) == -1)
			err(1, "%s: vasprintf", __func__);
		evbuffer_add_printf(buffer, "%s: %s\n", filename, data);
		free(data);
	}
	va_end(ap);
	return (0);
}

int
yyprintf(char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	if (buffer == NULL) {
		vfprintf(stdout, fmt, ap);
	} else {
		char *data;
		if (vasprintf(&data, fmt, ap) == -1)
			err(1, "%s: vasprintf", __func__);
		evbuffer_add_printf(buffer, "%s", data);
		free(data);
	}
	va_end(ap);
	return (0);
}

int
parse_configuration(FILE *input, char *name)
{
	extern FILE *yyin;

	buffer = NULL;
	errors = 0;
	lineno = 1;
	filename = name;
	yyin = input;
	yyparse();
	return (errors ? -1 : 0);
}

/*
 * Parse from memory.  Error output is buffered
 */

int
parse_line(struct evbuffer *output, char *line)
{
	void *yybuf;

	buffer = output;
	errors = 0;
	lineno = 1;
	filename = "<stdin>";
	yybuf = yy_scan_string(line);
	yyparse();
	yy_delete_buffer(yybuf);
	return (errors ? -1 : 0);
}
#line 768 "parse.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
#if defined(__cplusplus) || defined(__STDC__)
static int yygrowstack(void)
#else
static int yygrowstack()
#endif
{
    int newsize, i;
    short *newss;
    YYSTYPE *newvs;

    if ((newsize = yystacksize) == 0)
        newsize = YYINITSTACKSIZE;
    else if (newsize >= YYMAXDEPTH)
        return -1;
    else if ((newsize *= 2) > YYMAXDEPTH)
        newsize = YYMAXDEPTH;
    i = yyssp - yyss;
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
      (short *)malloc(newsize * sizeof *newss);
    if (newss == NULL)
        goto bail;
    yyss = newss;
    yyssp = newss + i;
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
      (YYSTYPE *)malloc(newsize * sizeof *newvs);
    if (newvs == NULL)
        goto bail;
    yyvs = newvs;
    yyvsp = newvs + i;
    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
#if defined(__cplusplus) || defined(__STDC__)
yyparse(void)
#else
yyparse()
#endif
{
    int yym, yyn, yystate;
#if YYDEBUG
#if defined(__cplusplus) || defined(__STDC__)
    const char *yys;
#else /* !(defined(__cplusplus) || defined(__STDC__)) */
    char *yys;
#endif /* !(defined(__cplusplus) || defined(__STDC__)) */

    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(lint) || defined(__GNUC__)
    goto yynewerror;
#endif
yynewerror:
    yyerror("syntax error");
#if defined(lint) || 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];
    yyval = yyvsp[1-yym];
    switch (yyn)
    {
case 12:
#line 172 "parse.y"
{
		if (template_create(yyvsp[0].string) == NULL)
			yyerror("Template \"%s\" exists already", yyvsp[0].string);
		free(yyvsp[0].string);
	}
break;
case 13:
#line 178 "parse.y"
{
		if (template_create("template") == NULL)
			yyerror("Template \"template\" exists already");
	}
break;
case 14:
#line 183 "parse.y"
{
		if (template_create("default") == NULL)
			yyerror("Template \"default\" exists already");
	}
break;
case 15:
#line 188 "parse.y"
{		
		struct template *tmpl;
		if ((tmpl = template_create(yyvsp[0].string)) == NULL)
			yyerror("Template \"%s\" exists already", yyvsp[0].string);
		tmpl->flags |= TEMPLATE_DYNAMIC;
		free(yyvsp[0].string);
	}
break;
case 16:
#line 198 "parse.y"
{
		if (yyvsp[0].tmpl != NULL)
			template_free(yyvsp[0].tmpl);
	}
break;
case 17:
#line 203 "parse.y"
{
		struct port *port;
		if ((port = port_find(yyvsp[-3].tmpl, yyvsp[-2].number, yyvsp[0].number)) == NULL) {
			yyerror("Cannot find port %d in \"%s\"",
			    yyvsp[0].number, yyvsp[-3].tmpl->name);
		} else {
			port_free(yyvsp[-3].tmpl, port);
		}
	}
break;
case 18:
#line 214 "parse.y"
{
		struct action *action;

		if (yyvsp[-4].tmpl == NULL) {
			yyerror("No template");
			break;
		}
		
		if ((action = honeyd_protocol(yyvsp[-4].tmpl, yyvsp[-3].number)) == NULL) {
			yyerror("Bad protocol");
			break;
		}
		if (yyvsp[-4].tmpl != NULL && template_add(yyvsp[-4].tmpl, yyvsp[-3].number, yyvsp[-1].number, &yyvsp[0].action) == -1)
			yyerror("Cannot add port %d to template \"%s\"",
			    yyvsp[-1].number, yyvsp[-4].tmpl != NULL ? yyvsp[-4].tmpl->name : "<unknown>");
		if (yyvsp[0].action.action)
			free(yyvsp[0].action.action);
	}
break;
case 19:
#line 233 "parse.y"
{	
		if (yyvsp[-4].tmpl == NULL || yyvsp[-2].tmpl == NULL)
			break;
		if (!(yyvsp[-4].tmpl->flags & TEMPLATE_DYNAMIC))
			yyerror("Cannot add templates to non-dynamic template \"%s\"", yyvsp[-4].tmpl->name);
		template_insert_dynamic(yyvsp[-4].tmpl, yyvsp[-2].tmpl, &yyvsp[0].condition);
	}
break;
case 20:
#line 241 "parse.y"
{	
		if (yyvsp[-3].tmpl == NULL || yyvsp[0].tmpl == NULL)
			break;
		if (!(yyvsp[-3].tmpl->flags & TEMPLATE_DYNAMIC))
			yyerror("Cannot add templates to non-dynamic template \"%s\"", yyvsp[-3].tmpl->name);
		template_insert_dynamic(yyvsp[-3].tmpl, yyvsp[0].tmpl, NULL);
	}
break;
case 21:
#line 250 "parse.y"
{
		int flags = 0;

		if (yyvsp[-1].number)
			flags |= SUBSYSTEM_SHARED;		
		if (yyvsp[0].number)
			flags |= SUBSYSTEM_RESTART;		

		yyvsp[-2].string[strlen(yyvsp[-2].string) - 1] = '\0';
		if (yyvsp[-4].tmpl != NULL &&
		    template_subsystem(yyvsp[-4].tmpl, yyvsp[-2].string+1, flags) == -1)
			yyerror("Can not add subsystem \"%s\" to template \"%s\"",
			    yyvsp[-2].string+1, yyvsp[-4].tmpl != NULL ? yyvsp[-4].tmpl->name : "<unknown>");
		free(yyvsp[-2].string);
	}
break;
case 22:
#line 267 "parse.y"
{
		/* Bind to an IP address and start subsystems */
		if (yyvsp[0].tmpl == NULL) {
			yyerror("Unknown template");
			break;
		}

		if (yyvsp[0].tmpl->ethernet_addr != NULL) {
			struct interface *inter;
			inter = interface_find_responsible(&yyvsp[-1].addr);
			if (inter == NULL ||
			    inter->if_ent.intf_link_addr.addr_type != ADDR_TYPE_ETH) {
				yyerror("Template \"%s\" is configured with "
				    "ethernet address but there is no "
				    "interface that can reach %s",
				    yyvsp[0].tmpl->name, addr_ntoa(&yyvsp[-1].addr));
				break;
			}
		}

		if (template_clone(addr_ntoa(&yyvsp[-1].addr), yyvsp[0].tmpl, NULL, 1) == NULL) {
			yyerror("Binding to %s failed", addr_ntoa(&yyvsp[-1].addr));
			break;
		}
	}
break;
case 23:
#line 293 "parse.y"
{
		struct template *tmpl;

		/* Special magic */
		if ((tmpl = template_find(addr_ntoa(&yyvsp[-1].addr))) != NULL) {
			if (!(tmpl->flags & TEMPLATE_DYNAMIC)) {
				yyerror("Template \"%s\" already specified as "
				    "non-dynamic template", addr_ntoa(&yyvsp[-1].addr));
				break;
			}
		} else if ((tmpl = template_create(addr_ntoa(&yyvsp[-1].addr))) == NULL) {
			yyerror("Could not create template \"%s\"",
			    addr_ntoa(&yyvsp[-1].addr));
			break;
		}
		tmpl->flags |= TEMPLATE_DYNAMIC;

		/* 
		 * Add this point we do have the right template.
		 * We just need to add the proper condition.
		 */
		template_insert_dynamic(tmpl, yyvsp[0].tmpl, &yyvsp[-2].condition);
	}
break;
case 24:
#line 317 "parse.y"
{
		struct interface *inter;
		struct template *tmpl;

		/* Bind an IP address to an external interface */
		if ((inter = interface_find(yyvsp[0].string)) == NULL) {
			yyerror("Interface \"%s\" does not exist.", yyvsp[0].string);
			free(yyvsp[0].string);
			break;
		}
		if (inter->if_ent.intf_link_addr.addr_type != ADDR_TYPE_ETH) {
			yyerror("Interface \"%s\" does not support ARP.", yyvsp[0].string);
			free(yyvsp[0].string);
			break;
		}

		if ((tmpl = template_create(addr_ntoa(&yyvsp[-2].addr))) == NULL) {
			yyerror("Template \"%s\" exists already",
			    addr_ntoa(&yyvsp[-2].addr));
			break;
		}

		/* Make this template external. */
		tmpl->flags |= TEMPLATE_EXTERNAL;
		tmpl->inter = inter;
		free(yyvsp[0].string);
	}
break;
case 25:
#line 345 "parse.y"
{		
		/* Automagically assign DHCP address */
		dhcp_template(yyvsp[-2].tmpl, yyvsp[0].string, NULL);
		free(yyvsp[0].string);
	}
break;
case 26:
#line 351 "parse.y"
{		
		/* Automagically assign DHCP address with MAC address */
		yyvsp[0].string[strlen(yyvsp[0].string) - 1] = '\0';
		dhcp_template(yyvsp[-4].tmpl, yyvsp[-2].string, yyvsp[0].string + 1);
		free(yyvsp[-2].string);
		free(yyvsp[0].string);
	}
break;
case 27:
#line 359 "parse.y"
{
		/* Just clone.  This is not the final destination yet */
		if (yyvsp[0].tmpl == NULL || template_clone(yyvsp[-1].string, yyvsp[0].tmpl, NULL, 0) == NULL)
			yyerror("Cloning to %s failed", yyvsp[-1].string);
		free(yyvsp[-1].string);
	}
break;
case 28:
#line 366 "parse.y"
{
		if (yyvsp[-3].tmpl == NULL) {
			yyerror("No template");
			break;
		}
		yyvsp[-3].tmpl->spoof.new_src = yyvsp[0].addr;
	}
break;
case 29:
#line 374 "parse.y"
{
		if (yyvsp[-3].tmpl == NULL) {
			yyerror("No template");
			break;
		}
		yyvsp[-3].tmpl->spoof.new_dst = yyvsp[0].addr;
	}
break;
case 30:
#line 382 "parse.y"
{
		if (yyvsp[-5].tmpl == NULL) {
			yyerror("No template");
			break;
		}
		yyvsp[-5].tmpl->spoof.new_src = yyvsp[-2].addr;
		yyvsp[-5].tmpl->spoof.new_dst = yyvsp[0].addr;
	}
break;
case 31:
#line 392 "parse.y"
{
		struct action *action;

		if (yyvsp[-4].tmpl == NULL) {
			yyerror("No template");
			break;
		}
		
		if ((action = honeyd_protocol(yyvsp[-4].tmpl, yyvsp[-2].number)) == NULL) {
			yyerror("Bad protocol");
			break;
		}

		port_action_clone(action, &yyvsp[0].action);
		if (yyvsp[0].action.action != NULL)
			free(yyvsp[0].action.action);
	}
break;
case 32:
#line 410 "parse.y"
{
		if (yyvsp[-2].tmpl == NULL || yyvsp[0].pers == NULL)
			break;
		yyvsp[-2].tmpl->person = personality_clone(yyvsp[0].pers);
	}
break;
case 33:
#line 416 "parse.y"
{
		extern int need_arp;
		if (yyvsp[-2].tmpl == NULL || yyvsp[0].string == NULL)
			break;
		yyvsp[0].string[strlen(yyvsp[0].string) - 1] = '\0';
		yyvsp[-2].tmpl->ethernet_addr = ethernetcode_make_address(yyvsp[0].string + 1);
		if (yyvsp[-2].tmpl->ethernet_addr == NULL) {
			yyerror("Unknown ethernet vendor \"%s\"", yyvsp[0].string + 1);
		}
		free (yyvsp[0].string);

		need_arp = 1;
	}
break;
case 34:
#line 430 "parse.y"
{
		if (yyvsp[-2].tmpl == NULL || yyvsp[0].number == 0)
			break;
		yyvsp[-2].tmpl->timestamp = yyvsp[0].number * 2;
	}
break;
case 35:
#line 436 "parse.y"
{
		if (yyvsp[-3].tmpl == NULL)
			break;
		if (yyvsp[0].floatp > 100) {
			yyerror("Droprate too high: %f", yyvsp[0].floatp);
			break;
		}

		yyvsp[-3].tmpl->drop_inrate = yyvsp[0].floatp * 100;
	}
break;
case 36:
#line 447 "parse.y"
{
		if (yyvsp[-3].tmpl == NULL)
			break;
		if (yyvsp[0].floatp > 100) {
			yyerror("Droprate too high: %f", yyvsp[0].floatp);
			break;
		}

		yyvsp[-3].tmpl->drop_synrate = yyvsp[0].floatp * 100;
	}
break;
case 37:
#line 458 "parse.y"
{
		if (yyvsp[-2].tmpl == NULL)
			break;
		if (yyvsp[0].number <= 3) {
			yyerror("Bad number of max file descriptors %d", yyvsp[0].number);
			break;
		}
		yyvsp[-2].tmpl->max_nofiles = yyvsp[0].number;
	}
break;
case 38:
#line 468 "parse.y"
{
		if (yyvsp[-2].tmpl == NULL)
			break;
		if (!yyvsp[0].number) {
			yyerror("Bad uid %d", yyvsp[0].number);
			break;
		}
		yyvsp[-2].tmpl->uid = yyvsp[0].number;
		honeyd_use_uid(yyvsp[0].number);
	}
break;
case 39:
#line 479 "parse.y"
{
		if (yyvsp[-4].tmpl == NULL)
			break;
		if (!yyvsp[-2].number || !yyvsp[0].number) {
			yyerror("Bad uid %d, gid %d", yyvsp[-2].number, yyvsp[0].number);
			break;
		}
		yyvsp[-4].tmpl->uid = yyvsp[-2].number;
		yyvsp[-4].tmpl->gid = yyvsp[0].number;
		honeyd_use_uid(yyvsp[-2].number);
		honeyd_use_gid(yyvsp[0].number);
	}
break;
case 40:
#line 493 "parse.y"
{
		if (yyvsp[-1].pers == NULL)
			break;
		yyvsp[-1].pers->disallow_finscan = !yyvsp[0].number;
	}
break;
case 41:
#line 499 "parse.y"
{
		if (yyvsp[-1].pers == NULL)
			break;
		yyvsp[-1].pers->fragp = yyvsp[0].fragp;
	}
break;
case 42:
#line 506 "parse.y"
{
		if (router_start(&yyvsp[0].addr, NULL) == -1)
			yyerror("Defining entry point failed: %s",
			    addr_ntoa(&yyvsp[0].addr));
	}
break;
case 43:
#line 512 "parse.y"
{
		if (router_start(&yyvsp[-2].addr, &yyvsp[0].addr) == -1)
			yyerror("Defining entry point failed: %s",
			    addr_ntoa(&yyvsp[-2].addr));
	}
break;
case 44:
#line 518 "parse.y"
{
		struct router *r, *newr;
		struct addr defroute;

		if ((r = router_find(&yyvsp[-8].addr)) == NULL &&
		    (r = router_new(&yyvsp[-8].addr)) == NULL) {
			yyerror("Cannot make forward reference for router %s",
			    addr_ntoa(&yyvsp[-8].addr));
			break;
		}
		if ((newr = router_find(&yyvsp[-4].addr)) == NULL)
			newr = router_new(&yyvsp[-4].addr);
		if (router_add_net(r, &yyvsp[-5].addr, newr, yyvsp[-3].number, yyvsp[-2].number, yyvsp[-1].number, &yyvsp[0].drop) == -1)
			yyerror("Could not add route to %s", addr_ntoa(&yyvsp[-5].addr));

		if (yyvsp[-1].number == 0 && yyvsp[0].drop.high != 0)
			yywarn("Ignoring drop between statement without "
			       "specified bandwidth.");

		addr_pton("0.0.0.0/0", &defroute);
		defroute.addr_bits = 0; /* work around libdnet bug */

		/* Only insert a reverse route, if the current route is
		 * not the default route.
		 */
		if (addr_cmp(&defroute, &yyvsp[-5].addr) != 0 &&
		    router_add_net(newr, &defroute, r, yyvsp[-3].number, yyvsp[-2].number, yyvsp[-1].number, &yyvsp[0].drop) == -1)
			yyerror("Could not add default route to %s",
			    addr_ntoa(&yyvsp[-5].addr));
	}
break;
case 45:
#line 549 "parse.y"
{
		struct router *r;

		if ((r = router_find(&yyvsp[-6].addr)) == NULL &&
		    (r = router_new(&yyvsp[-6].addr)) == NULL) {
			yyerror("Cannot make forward reference for router %s",
			    addr_ntoa(&yyvsp[-6].addr));
			break;
		}
		if (router_add_tunnel(r, &yyvsp[-3].addr, &yyvsp[-1].addr, &yyvsp[0].addr) == -1)
			yyerror("Could not add tunnel to %s", addr_ntoa(&yyvsp[0].addr));
	}
break;
case 46:
#line 562 "parse.y"
{
		struct router *r;

		if ((r = router_find(&yyvsp[-2].addr)) == NULL &&
		    (r = router_new(&yyvsp[-2].addr)) == NULL) {
			yyerror("Cannot make forward reference for router %s",
			    addr_ntoa(&yyvsp[-2].addr));
			break;
		}
		if (router_add_link(r, &yyvsp[0].addr) == -1)
			yyerror("Could not add link %s", addr_ntoa(&yyvsp[0].addr));
	}
break;
case 47:
#line 575 "parse.y"
{
		struct router *r;

		if ((r = router_find(&yyvsp[-2].addr)) == NULL &&
		    (r = router_new(&yyvsp[-2].addr)) == NULL) {
			yyerror("Cannot make forward reference for router %s",
			    addr_ntoa(&yyvsp[-2].addr));
			break;
		}
		if (router_add_unreach(r, &yyvsp[0].addr) == -1)
			yyerror("Could not add unreachable net %s",
			    addr_ntoa(&yyvsp[0].addr));
	}
break;
case 48:
#line 589 "parse.y"
{ yyval.number = 1; }
break;
case 49:
#line 590 "parse.y"
{ yyval.number = 0; }
break;
case 50:
#line 592 "parse.y"
{ yyval.fragp = FRAG_DROP; }
break;
case 51:
#line 593 "parse.y"
{ yyval.fragp = FRAG_OLD; }
break;
case 52:
#line 594 "parse.y"
{ yyval.fragp = FRAG_NEW; }
break;
case 53:
#line 597 "parse.y"
{
		if (addr_pton(yyvsp[0].string, &yyval.addr) < 0)
			yyerror("Illegal IP address %s", yyvsp[0].string);
		free(yyvsp[0].string);
	}
break;
case 54:
#line 603 "parse.y"
{
		struct addrinfo ai, *aitop;

		memset(&ai, 0, sizeof (ai));
		ai.ai_family = AF_INET;
		ai.ai_socktype = 0;
		ai.ai_flags = 0;

		/* Remove quotation marks */
		yyvsp[0].string[strlen(yyvsp[0].string) - 1] = '\0';
		if (getaddrinfo(yyvsp[0].string+1, NULL, &ai, &aitop) != 0) {
			yyerror("getaddrinfo failed: %s", yyvsp[0].string+1);
			break;
		}
		addr_ston(aitop->ai_addr, &yyval.addr);
		freeaddrinfo(aitop);
		free(yyvsp[0].string);
	}
break;
case 55:
#line 623 "parse.y"
{
		char src[25];
		struct addr b;
		snprintf(src, sizeof(src), "%s/%d",
		    addr_ntoa(&yyvsp[-2].addr), yyvsp[0].number);
		if (addr_pton(src, &yyval.addr) < 0)
			yyerror("Illegal IP network %s", src);
		/* Fix libdnet error */
		if (yyvsp[0].number == 0)
			yyval.addr.addr_bits = 0;

		/* Test if this is a legal network */
		addr_net(&yyval.addr, &b);
		b.addr_bits = yyval.addr.addr_bits;
		if (memcmp(&yyval.addr.addr_ip, &b.addr_ip, IP_ADDR_LEN)) {
			yyval.addr = b;
			yywarn("Bad network mask in %s", src);
		}
	}
break;
case 56:
#line 644 "parse.y"
{
		if (curtype == -1) {
			yyerror("Bad port type");
			break;
		}
		yyval.ai = cmd_proxy_getinfo(addr_ntoa(&yyvsp[-2].addr), curtype, yyvsp[0].number);
		curtype = -1;
		if (yyval.ai == NULL)
			yyerror("Illegal IP address port pair");
	}
break;
case 57:
#line 656 "parse.y"
{
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyval.action.action = yyvsp[0].string;
		yyval.action.flags = yyvsp[-1].number;
		yyval.action.status = PORT_OPEN;
	}
break;
case 58:
#line 663 "parse.y"
{
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyvsp[0].string[strlen(yyvsp[0].string) - 1] = '\0';
		if ((yyval.action.action = strdup(yyvsp[0].string + 1)) == NULL)
			yyerror("Out of memory");
		yyval.action.status = PORT_OPEN;
		yyval.action.flags = yyvsp[-1].number;
		free(yyvsp[0].string);
	}
break;
case 59:
#line 673 "parse.y"
{
#ifdef HAVE_PYTHON
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyvsp[0].string[strlen(yyvsp[0].string) - 1] = '\0';
		if ((yyval.action.action_extend = pyextend_load_module(yyvsp[0].string+1)) == NULL)
			yyerror("Bad python module: \"%s\"", yyvsp[0].string+1);
		yyval.action.status = PORT_PYTHON;
		yyval.action.flags = yyvsp[-2].number;
		free(yyvsp[0].string);
#else
		yyerror("Python support is not available.");
#endif
	}
break;
case 60:
#line 687 "parse.y"
{
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyval.action.status = PORT_PROXY;
		yyval.action.action = NULL;
		yyval.action.aitop = yyvsp[0].ai;
		yyval.action.flags = yyvsp[-2].number;
	}
break;
case 61:
#line 695 "parse.y"
{
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyval.action.status = PORT_PROXY;
		yyval.action.action = NULL;
		yyval.action.aitop = NULL;
		yyval.action.flags = yyvsp[-4].number;
		if (yyvsp[-2].string[0] != '$') {
			if (curtype == -1) {
				yyerror("Bad port type");
				break;
			}
			yyval.action.aitop = cmd_proxy_getinfo(yyvsp[-2].string, curtype, yyvsp[0].number);
			curtype = -1;
			if (yyval.action.aitop == NULL)
				yyerror("Illegal host name in proxy");
		} else {
			char proxy[1024];

			snprintf(proxy, sizeof(proxy), "%s:%d", yyvsp[-2].string, yyvsp[0].number);
			yyval.action.action = strdup(proxy);
			if (yyval.action.action == NULL)
				yyerror("Out of memory");
		}
		free(yyvsp[-2].string);
	}
break;
case 62:
#line 721 "parse.y"
{
		char proxy[1024];
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyval.action.status = PORT_PROXY;
		yyval.action.action = NULL;
		yyval.action.aitop = NULL;
		yyval.action.flags = yyvsp[-4].number;

		snprintf(proxy, sizeof(proxy), "%s:%s", yyvsp[-2].string, yyvsp[0].string);
		yyval.action.action = strdup(proxy);
		if (yyval.action.action == NULL)
				yyerror("Out of memory");
		free(yyvsp[-2].string);
		free(yyvsp[0].string);
	}
break;
case 63:
#line 737 "parse.y"
{
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyval.action.status = PORT_BLOCK;
		yyval.action.action = NULL;
	}
break;
case 64:
#line 743 "parse.y"
{
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyval.action.status = PORT_RESET;
		yyval.action.action = NULL;
	}
break;
case 65:
#line 749 "parse.y"
{
		memset(&yyval.action, 0, sizeof(yyval.action));
		yyval.action.status = PORT_OPEN;
		yyval.action.action = NULL;
		yyval.action.flags = yyvsp[-1].number;
	}
break;
case 66:
#line 758 "parse.y"
{
		yyval.tmpl = template_find(yyvsp[0].string);
		if (yyval.tmpl == NULL)
			yyerror("Unknown template \"%s\"", yyvsp[0].string);
		free(yyvsp[0].string);
	}
break;
case 67:
#line 765 "parse.y"
{
		yyval.tmpl = template_find("template");
		if (yyval.tmpl == NULL)
			yyerror("Unknown template \"%s\"", "template");
	}
break;
case 68:
#line 771 "parse.y"
{
		yyval.tmpl = template_find("default");
		if (yyval.tmpl == NULL)
			yyerror("Unknown template \"%s\"", "default");
	}
break;
case 69:
#line 777 "parse.y"
{
		yyval.tmpl = template_find(addr_ntoa(&yyvsp[0].addr));
		if (yyval.tmpl == NULL)
			yyerror("Unknown template \"%s\"", addr_ntoa(&yyvsp[0].addr));
	}
break;
case 70:
#line 784 "parse.y"
{
		yyvsp[0].string[strlen(yyvsp[0].string) - 1] = '\0';
		yyval.pers = personality_find(yyvsp[0].string+1);
		if (yyval.pers == NULL)
			yyerror("Unknown personality \"%s\"", yyvsp[0].string+1);
		free(yyvsp[0].string);
	}
break;
case 71:
#line 792 "parse.y"
{
		yyval.pers = personality_random();
		if (yyval.pers == NULL)
			yyerror("Random personality failed");
	}
break;
case 72:
#line 799 "parse.y"
{
		yyval.floatp = yyvsp[0].floatp;
	}
break;
case 73:
#line 803 "parse.y"
{
		yyval.floatp = yyvsp[0].number;
	}
break;
case 74:
#line 807 "parse.y"
{ yyval.number = 0; }
break;
case 75:
#line 809 "parse.y"
{
		yyval.number = yyvsp[-1].number;
	}
break;
case 76:
#line 813 "parse.y"
{ yyval.number = 0; }
break;
case 77:
#line 815 "parse.y"
{
		yyval.number = yyvsp[0].floatp * 100;
	}
break;
case 78:
#line 819 "parse.y"
{ yyval.number = 0; }
break;
case 79:
#line 821 "parse.y"
{
		yyval.number = yyvsp[-1].number * yyvsp[0].number;
	}
break;
case 80:
#line 825 "parse.y"
{
		yyval.number = yyvsp[0].number;
	}
break;
case 81:
#line 829 "parse.y"
{ memset(&yyval.drop, 0, sizeof(yyval.drop)); }
break;
case 82:
#line 831 "parse.y"
{
		if (yyvsp[-1].number <= yyvsp[-4].number)
			yyerror("Incorrect thresholds. First number needs to "
				"be smaller than second number.");
		yyval.drop.low = yyvsp[-4].number;
		yyval.drop.high = yyvsp[-1].number;
	}
break;
case 83:
#line 840 "parse.y"
{
		struct honeyd_plugin_cfg cfg;

		memset(&cfg, 0, sizeof(struct honeyd_plugin_cfg));
		cfg.cfg_int = yyvsp[0].number;
		cfg.cfg_type = HD_CONFIG_INT;
		plugins_config_item_add(yyvsp[-2].string, yyvsp[-1].string, &cfg);
		
		free(yyvsp[-2].string); free(yyvsp[-1].string);
	}
break;
case 84:
#line 851 "parse.y"
{
		struct honeyd_plugin_cfg cfg;

		memset(&cfg, 0, sizeof(struct honeyd_plugin_cfg));
		cfg.cfg_flt = yyvsp[0].floatp;
		cfg.cfg_type = HD_CONFIG_FLT;
		plugins_config_item_add(yyvsp[-2].string, yyvsp[-1].string, &cfg);

		free(yyvsp[-2].string); free(yyvsp[-1].string);
        }
break;
case 85:
#line 862 "parse.y"
{
		struct honeyd_plugin_cfg cfg;

		memset(&cfg, 0, sizeof(struct honeyd_plugin_cfg));
		cfg.cfg_str = yyvsp[0].string;
		cfg.cfg_type = HD_CONFIG_STR;
		plugins_config_item_add(yyvsp[-2].string, yyvsp[-1].string, &cfg);

		free(yyvsp[-2].string); free(yyvsp[-1].string); free(yyvsp[0].string);
        }
break;
case 86:
#line 874 "parse.y"
{
		struct honeyd_plugin_cfg cfg;
		char path[MAXPATHLEN];

		snprintf(path, sizeof(path), "/%s", yyvsp[0].string);

		memset(&cfg, 0, sizeof(struct honeyd_plugin_cfg));
		cfg.cfg_str = path;
		cfg.cfg_type = HD_CONFIG_STR;
		plugins_config_item_add(yyvsp[-3].string, yyvsp[-2].string, &cfg);

		free(yyvsp[-3].string); free(yyvsp[-2].string); free(yyvsp[0].string);
        }
break;
case 87:
#line 890 "parse.y"
{
	template_list_glob(buffer, "*");
}
break;
case 88:
#line 894 "parse.y"
{
	yyvsp[0].string[strlen(yyvsp[0].string)-1] = '\0';

	template_list_glob(buffer, yyvsp[0].string+1);

	free (yyvsp[0].string);
}
break;
case 89:
#line 902 "parse.y"
{
	template_list_glob(buffer, yyvsp[0].string);
}
break;
case 90:
#line 906 "parse.y"
{
	template_subsystem_list_glob(buffer, "*");
}
break;
case 91:
#line 910 "parse.y"
{
	template_subsystem_list_glob(buffer, yyvsp[0].string);
}
break;
case 92:
#line 914 "parse.y"
{
	yyvsp[0].string[strlen(yyvsp[0].string)-1] = '\0';
	template_subsystem_list_glob(buffer, yyvsp[0].string+1);
	free(yyvsp[0].string);
}
break;
case 93:
#line 920 "parse.y"
{
	if (strcasecmp(yyvsp[-1].string, "fd") == 0) {
		yyprintf("%d: %d\n", yyvsp[0].number, fdshare_inspect(yyvsp[0].number));
	} else if (strcasecmp(yyvsp[-1].string, "trace") == 0) {
		struct evbuffer *evbuf = evbuffer_new();
		if (evbuf == NULL)
			err(1, "%s: malloc");

		trace_inspect(yyvsp[0].number, evbuf);

		yyprintf("%s", EVBUFFER_DATA(evbuf));

		evbuffer_free(evbuf);
	} else {
		yyerror("Unsupported debug command: \"%s\"\n", yyvsp[-1].string);
	}
	free(yyvsp[-1].string);
}
break;
case 94:
#line 940 "parse.y"
{
	yyval.number = 0;
}
break;
case 95:
#line 944 "parse.y"
{
	yyval.number = 1;
}
break;
case 96:
#line 950 "parse.y"
{
	yyval.number = 0;
}
break;
case 97:
#line 954 "parse.y"
{
	yyval.number = 1;
}
break;
case 98:
#line 960 "parse.y"
{
	yyval.number = 0;
}
break;
case 99:
#line 964 "parse.y"
{
	yyval.number = PORT_TARPIT;
}
break;
case 100:
#line 970 "parse.y"
{
		pf_osfp_t fp;
		yyvsp[0].string[strlen(yyvsp[0].string) - 1] = '\0';
		if ((fp = pfctl_get_fingerprint(yyvsp[0].string+1)) == PF_OSFP_NOMATCH)
			yyerror("Unknown fingerprint \"%s\"", yyvsp[0].string+1);
		if ((yyval.condition.match_arg = malloc(sizeof(fp))) == NULL)
			yyerror("Out of memory");
		memcpy(yyval.condition.match_arg, &fp, sizeof(fp));
		yyval.condition.match = condition_match_osfp;
		yyval.condition.match_arglen = sizeof(fp);
		free (yyvsp[0].string);
	}
break;
case 101:
#line 983 "parse.y"
{
		if ((yyval.condition.match_arg = malloc(sizeof(struct addr))) == NULL)
			yyerror("Out of memory");
		memcpy(yyval.condition.match_arg, &yyvsp[0].addr, sizeof(struct addr));
		yyval.condition.match = condition_match_addr;
		yyval.condition.match_arglen = sizeof(struct addr);
	}
break;
case 102:
#line 991 "parse.y"
{
		if ((yyval.condition.match_arg = malloc(sizeof(struct addr))) == NULL)
			yyerror("Out of memory");
		memcpy(yyval.condition.match_arg, &yyvsp[0].addr, sizeof(struct addr));
		yyval.condition.match = condition_match_addr;
		yyval.condition.match_arglen = sizeof(struct addr);
	}
break;
case 103:
#line 999 "parse.y"
{
		if ((yyval.condition.match_arg = malloc(sizeof(struct condition_time))) == NULL)
			yyerror("Out of memory");
		memcpy(yyval.condition.match_arg, &yyvsp[0].timecondition, sizeof(struct condition_time));
		yyval.condition.match = condition_match_time;
		yyval.condition.match_arglen = sizeof(struct condition_time);
	}
break;
case 104:
#line 1007 "parse.y"
{
		if ((yyval.condition.match_arg = malloc(sizeof(struct addr))) == NULL)
			yyerror("Out of memory");
		memcpy(yyval.condition.match_arg, &yyvsp[0].number, sizeof(int));
		yyval.condition.match = condition_match_proto;
		yyval.condition.match_arglen = sizeof(int);
	}
break;
case 105:
#line 1015 "parse.y"
{
		yyval.condition.match_arg = 0;
		yyval.condition.match = condition_match_otherwise;
		yyval.condition.match_arglen = 0;
	}
break;
case 106:
#line 1023 "parse.y"
{
		yyval.timecondition.tm_start = yyvsp[-2].time;
		yyval.timecondition.tm_end = yyvsp[0].time;
	}
break;
case 107:
#line 1030 "parse.y"
{
		int ispm = -1;
		int hour, minute;

		if (strcmp(yyvsp[0].string, "am") == 0) {
			ispm = 0;
		} else if (strcmp(yyvsp[0].string, "pm") == 0) {
			ispm = 1;
		} else {
			yyerror("Bad time specifier, use 'am' or 'pm': %s", yyvsp[0].string);
			break;
		}
		free (yyvsp[0].string);

		hour = yyvsp[-3].number + (ispm ? 12 : 0);
		minute = yyvsp[-1].number;

		memset(&yyval.time, 0, sizeof(yyval.time));
		yyval.time.tm_hour = hour;
		yyval.time.tm_min = minute;
	}
break;
case 108:
#line 1052 "parse.y"
{
		char *time = yyvsp[0].string + 1;
		time[strlen(time)-1] = '\0';

		if (strptime(time, "%T", &yyval.time) != NULL) {
			; /* done */
		} else if (strptime(time, "%r", &yyval.time) != NULL) {
			; /* done */
		} else {
			yyerror("Bad time specification; use \"hh:mm:ss\"");
		}

		free(yyvsp[0].string);
	}
break;
#line 2022 "parse.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);
}
