/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mDNSEmbeddedAPI.h"
#include "DebugServices.h"
#include "dnsextd.h"

void yyerror( const char* error );
int  yylex(void);


typedef struct StringListElem
{
	char					*	string;
	struct StringListElem	*	next;
} StringListElem;


typedef struct OptionsInfo
{
	char	server_address[ 256 ];
	int		server_port;
	char	source_address[ 256 ];
	int		source_port;
	int		private_port;
	int		llq_port;
} OptionsInfo;


typedef struct ZoneInfo
{
	char	name[ 256 ];
	char	certificate_name[ 256 ];
	char	allow_clients_file[ 256 ];
	char	allow_clients[ 256 ];
	char	key[ 256 ];
} ZoneInfo;


typedef struct KeySpec
{
	char 				name[ 256 ];
	char				algorithm[ 256 ];
	char				secret[ 256 ];
	struct KeySpec	*	next;
} KeySpec;


typedef struct ZoneSpec
{
	char				name[ 256 ];
	DNSZoneSpecType		type;
	StringListElem	*	allowUpdate;
	StringListElem	*	allowQuery;
	char				key[ 256 ];
	struct ZoneSpec	*	next;
} ZoneSpec;


static StringListElem	*	g_stringList = NULL;
static KeySpec			*	g_keys;
static ZoneSpec			*	g_zones;
static ZoneSpec				g_zoneSpec;
static const char		*	g_filename;

#define YYPARSE_PARAM  context

void
SetupOptions
	(
	OptionsInfo	*	info,
	void		*	context
	);

%}

%union
{
	int			number;
	char	*	string;
}

%token	OPTIONS 
%token	LISTEN_ON 
%token	NAMESERVER
%token	PORT 
%token	ADDRESS 
%token	LLQ 
%token	PUBLIC
%token  PRIVATE
%token  ALLOWUPDATE
%token  ALLOWQUERY
%token	KEY 
%token  ALGORITHM
%token  SECRET
%token  ISSUER
%token  SERIAL
%token	ZONE
%token  TYPE
%token	ALLOW
%token	OBRACE 
%token	EBRACE 
%token	SEMICOLON
%token 	IN
%token	<string>	DOTTED_DECIMAL_ADDRESS 
%token	<string>	WILDCARD 
%token	<string>	DOMAINNAME 
%token	<string>	HOSTNAME 
%token	<string>	QUOTEDSTRING
%token	<number> 	NUMBER 

%type	<string>	addressstatement
%type	<string>	networkaddress

%%

commands:
        |        
        commands command SEMICOLON
        ;


command:
		options_set
		|
        zone_set 
		|
		key_set
        ;


options_set:
		OPTIONS optionscontent
		{
			// SetupOptions( &g_optionsInfo, context );
		}
		;

optionscontent:
		OBRACE optionsstatements EBRACE
		;

optionsstatements:
		|
		optionsstatements optionsstatement SEMICOLON
		;


optionsstatement:
		statements
		|
		LISTEN_ON addresscontent
		{
		}
		|
		LISTEN_ON PORT NUMBER addresscontent
		{
		}
		|
		NAMESERVER ADDRESS networkaddress
		{
		}
		|
		NAMESERVER ADDRESS networkaddress PORT NUMBER
		{
		}
		|
		PRIVATE PORT NUMBER
		{
			( ( DaemonInfo* ) context )->private_port = mDNSOpaque16fromIntVal( $3 );
		}
		|
		LLQ PORT NUMBER
		{
			( ( DaemonInfo* ) context )->llq_port = mDNSOpaque16fromIntVal( $3 );
		}
		;

key_set:
        KEY QUOTEDSTRING OBRACE SECRET QUOTEDSTRING SEMICOLON EBRACE
        {
			KeySpec	* keySpec;

			keySpec = ( KeySpec* ) malloc( sizeof( KeySpec ) );

			if ( !keySpec )
				{
				LogMsg("ERROR: memory allocation failure");
				YYABORT;
				}

			strncpy( keySpec->name, $2, sizeof( keySpec->name ) );
			strncpy( keySpec->secret, $5, sizeof( keySpec->secret ) );

			keySpec->next	= g_keys;
			g_keys			= keySpec;
        }
        ;

zone_set:
		ZONE QUOTEDSTRING zonecontent
		{
			ZoneSpec * zoneSpec;

			zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );

			if ( !zoneSpec )
				{
				LogMsg("ERROR: memory allocation failure");
				YYABORT;
				}

			strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
			zoneSpec->type = g_zoneSpec.type;
			strcpy( zoneSpec->key, g_zoneSpec.key );
			zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
			zoneSpec->allowQuery = g_zoneSpec.allowQuery;

			zoneSpec->next = g_zones;
			g_zones = zoneSpec;
		}
		|
		ZONE QUOTEDSTRING IN zonecontent
        {
			ZoneSpec * zoneSpec;

			zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );

			if ( !zoneSpec )
				{
				LogMsg("ERROR: memory allocation failure");
				YYABORT;
				}

			strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
			zoneSpec->type = g_zoneSpec.type;
			strcpy( zoneSpec->key, g_zoneSpec.key );
			zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
			zoneSpec->allowQuery = g_zoneSpec.allowQuery;

			zoneSpec->next = g_zones;
			g_zones = zoneSpec;
		}
        ;

zonecontent:
		OBRACE zonestatements EBRACE 

zonestatements:
        |
        zonestatements zonestatement SEMICOLON
        ;

zonestatement:
		TYPE PUBLIC
		{
			g_zoneSpec.type = kDNSZonePublic;
		}
		|
		TYPE PRIVATE
		{
			g_zoneSpec.type = kDNSZonePrivate;
		}
		|
		ALLOWUPDATE keycontent
		{
			g_zoneSpec.allowUpdate = g_stringList;
			g_stringList = NULL;
		}
		|
		ALLOWQUERY keycontent
		{
			g_zoneSpec.allowQuery = g_stringList;
			g_stringList = NULL;
		}
        ;

addresscontent:
		OBRACE addressstatements EBRACE
		{
		}

addressstatements:
		|
		addressstatements addressstatement SEMICOLON
		{
		}
		;

addressstatement:
		DOTTED_DECIMAL_ADDRESS
		{
		}
		;


keycontent:
		OBRACE keystatements EBRACE
		{
		}

keystatements:
		|
		keystatements keystatement SEMICOLON
		{
		}
		;

keystatement:
		KEY DOMAINNAME
		{
			StringListElem * elem;

			elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );

			if ( !elem )
				{
				LogMsg("ERROR: memory allocation failure");
				YYABORT;
				}

			elem->string = $2;

			elem->next		= g_stringList;
			g_stringList	= elem;
		}
		;


networkaddress:
		DOTTED_DECIMAL_ADDRESS
		|
		HOSTNAME
		|
		WILDCARD
		;

block: 
		OBRACE zonestatements EBRACE SEMICOLON
        ;

statements:
        |
		statements statement
        ;

statement:
		block
		{
			$<string>$ = NULL;
		}
		|
		QUOTEDSTRING
		{
			$<string>$ = $1;
		}
%%

int yywrap(void);

extern int yylineno;

void yyerror( const char *str )
{
        fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
}
 
int yywrap()
{
        return 1;
} 


int
ParseConfig
	(
	DaemonInfo	*	d,
	const char	*	file
	)
	{
	extern FILE		*	yyin;
	DNSZone			*	zone;
	DomainAuthInfo	*	key;
	KeySpec			*	keySpec;
	ZoneSpec		*	zoneSpec;
	int					err = 0;

	g_filename = file;

	// Tear down the current zone specifiers

	zone = d->zones;

	while ( zone )
		{
		DNSZone * next = zone->next;

		key = zone->updateKeys;

		while ( key )
			{
			DomainAuthInfo * nextKey = key->next;

			free( key );

			key = nextKey;
			}

		key = zone->queryKeys;

		while ( key )
			{
			DomainAuthInfo * nextKey = key->next;

			free( key );

			key = nextKey;
			}

		free( zone );

		zone = next;
		}

	d->zones = NULL;
	
	yyin = fopen( file, "r" );
	require_action( yyin, exit, err = 0 );

	err = yyparse( ( void* ) d );
	require_action( !err, exit, err = 1 );

	for ( zoneSpec = g_zones; zoneSpec; zoneSpec = zoneSpec->next )
		{
		StringListElem  *   elem;
		mDNSu8			*	ok;

		zone = ( DNSZone* ) malloc( sizeof( DNSZone ) );
		require_action( zone, exit, err = 1 );
		memset( zone, 0, sizeof( DNSZone ) );

		zone->next	= d->zones;
		d->zones	= zone;

		// Fill in the domainname

		ok = MakeDomainNameFromDNSNameString( &zone->name, zoneSpec->name );
		require_action( ok, exit, err = 1 );

		// Fill in the type

		zone->type = zoneSpec->type;

		// Fill in the allow-update keys

		for ( elem = zoneSpec->allowUpdate; elem; elem = elem->next )
			{
			mDNSBool found = mDNSfalse;

			for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
				{
				if ( strcmp( elem->string, keySpec->name ) == 0 )
					{
					DomainAuthInfo	*	authInfo = malloc( sizeof( DomainAuthInfo ) );
					mDNSs32				keylen;
					require_action( authInfo, exit, err = 1 );
					memset( authInfo, 0, sizeof( DomainAuthInfo ) );

					ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
					if (!ok) { free(authInfo); err = 1; goto exit; }

					keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
					if (keylen < 0) { free(authInfo); err = 1; goto exit; }

					authInfo->next = zone->updateKeys;
					zone->updateKeys = authInfo;

					found = mDNStrue;

					break;
					}
				}

			// Log this
			require_action( found, exit, err = 1 );
			}

		// Fill in the allow-query keys

		for ( elem = zoneSpec->allowQuery; elem; elem = elem->next )
			{
			mDNSBool found = mDNSfalse;

			for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
				{
				if ( strcmp( elem->string, keySpec->name ) == 0 )
					{
					DomainAuthInfo	*	authInfo = malloc( sizeof( DomainAuthInfo ) );
					mDNSs32				keylen;
					require_action( authInfo, exit, err = 1 );
					memset( authInfo, 0, sizeof( DomainAuthInfo ) );

					ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
					if (!ok) { free(authInfo); err = 1; goto exit; }

					keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
					if (keylen < 0) { free(authInfo); err = 1; goto exit; }

					authInfo->next = zone->queryKeys;
					zone->queryKeys = authInfo;

					found = mDNStrue;

					break;
					}
				}

			// Log this
			require_action( found, exit, err = 1 );
			}
		}

exit:

	return err;
	}


void
SetupOptions
	(
	OptionsInfo	*	info,
	void		*	context
	)
	{
	DaemonInfo * d = ( DaemonInfo* ) context;

	if ( strlen( info->source_address ) )
		{
		inet_pton( AF_INET, info->source_address, &d->addr.sin_addr );
		}

	if ( info->source_port )
		{
		d->addr.sin_port = htons( ( mDNSu16 ) info->source_port );
		}
				
	if ( strlen( info->server_address ) )
		{
		inet_pton( AF_INET, info->server_address, &d->ns_addr.sin_addr );
		}

	if ( info->server_port )
		{
		d->ns_addr.sin_port = htons( ( mDNSu16 ) info->server_port );
		}

	if ( info->private_port )
		{
		d->private_port = mDNSOpaque16fromIntVal( info->private_port );
		}

	if ( info->llq_port )
		{
		d->llq_port = mDNSOpaque16fromIntVal( info->llq_port );
		}
	}
