Commit 915440a0 authored by James Brister's avatar James Brister
Browse files

Files for the config file parsing.

parent f5375f2b
/*
* Copyright (C) 1998, 1999 Internet Software Consortium.
*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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 <config.h>
#include <isc/assertions.h>
#include "configctx.h"
static void freeoptions(isc_cfgoptions_t *opts, isc_mem_t *mem);
static isc_result_t setdirectory(isc_cfgoptions_t *opts, char *directory,
isc_mem_t *mem);
/***
*** PUBLIC
***/
isc_result_t
isc_cfg_newctx(isc_mem_t *mem, isc_cfgctx_t **ctx)
{
isc_cfgctx_t *cfg = NULL;
isc_cfgoptions_t *opts = NULL;
isc_zonectx_t *zonectx = NULL;
isc_result_t res;
INSIST(mem != NULL);
cfg = isc_mem_get(mem, sizeof *cfg);
if (cfg == NULL) {
return (ISC_R_NOMEMORY);
}
memset(cfg, 0x0, sizeof *cfg);
cfg->mem = mem;
opts = isc_mem_get(mem, sizeof *opts);
if (opts == NULL) {
isc_mem_put(mem, cfg, sizeof *cfg);
return (ISC_R_NOMEMORY);
}
memset (opts, 0x0, sizeof *opts);
cfg->options = opts;
if ((res = isc_zone_newcontext(mem, &zonectx)) != ISC_R_SUCCESS) {
isc_mem_put(mem, opts, sizeof *opts);
isc_mem_put(mem, cfg, sizeof *cfg);
return (res);
}
cfg->zonecontext = zonectx;
*ctx = cfg ;
return (ISC_R_SUCCESS);
}
isc_result_t
isc_cfg_freectx(isc_cfgctx_t **ctx)
{
isc_cfgctx_t *c ;
INSIST(ctx != NULL);
c = *ctx;
INSIST(c->mem != NULL);
if (c->options != NULL) {
freeoptions(c->options, c->mem);
}
isc_mem_put(c->mem, c, sizeof *c);
*ctx = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
isc_cfg_setdirectory(isc_cfgctx_t *ctx, char *directory)
{
INSIST(ctx != NULL);
INSIST(ctx->mem != NULL);
INSIST(directory != NULL);
INSIST(strlen(directory) > 0);
INSIST(ctx->options != NULL);
return (setdirectory(ctx->options, directory, ctx->mem));
}
/***
*** PRIVATE
***/
static isc_result_t
setdirectory(isc_cfgoptions_t *opts, char *directory, isc_mem_t *mem)
{
if (opts->directory != NULL && opts->dirlen <= strlen(directory)) {
isc_mem_put(mem, opts->directory, opts->dirlen);
opts->directory = NULL;
opts->dirlen = 0;
}
if (opts->dirlen == 0) {
int need = strlen(directory) + 1;
opts->directory = isc_mem_get(mem, need);
if (opts->directory == NULL) {
return (ISC_R_NOMEMORY);
}
opts->dirlen = need;
}
strcpy(opts->directory, directory);
return (ISC_R_SUCCESS);
}
static void
freeoptions(isc_cfgoptions_t *opts, isc_mem_t *mem)
{
INSIST(opts != NULL);
if (opts->directory != NULL) {
INSIST(opts->dirlen > 0);
} else {
INSIST(opts->dirlen == 0);
}
isc_mem_put(mem, opts->directory, opts->dirlen);
isc_mem_put(mem, opts, sizeof *opts);
}
/*
* Copyright (C) 1998, 1999 Internet Software Consortium.
*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
#if !defined(CONFIGCTX_H)
#define CONFIGCTX_H 1
#include <isc/mem.h>
#include "zone.h"
typedef struct isc_cfgoptions
{
size_t dirlen; /* XXX no counted strings? */
char *directory;
} isc_cfgoptions_t;
typedef struct isc_cfgctx
{
int warnings;
int errors;
isc_mem_t *mem;
isc_cfgoptions_t *options;
isc_zonectx_t *zonecontext;
/* XXX other config stuff like trusted keys, acls, logging etc. */
} isc_cfgctx_t;
isc_result_t isc_cfg_newctx(isc_mem_t *mem, isc_cfgctx_t **ctx);
isc_result_t isc_cfg_freectx(isc_cfgctx_t **ctx);
isc_result_t isc_cfg_setdirectory(isc_cfgctx_t *ctx, char *directory);
#endif
%{
#if !defined(lint) && !defined(SABER)
static char rcsid[] = "$Id: lexer.l,v 1.1 1999/01/30 00:50:10 brister Exp $";
#endif /* not lint */
/*
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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 <config.h>
#include <stdlib.h>
#include <string.h>
#include "zone.h"
#include "parser_p.h"
int yylex(void);
%}
qstring \"[^\"\n]*[\"\n]
intnum -?[0-9]+
ws [ \t]+
%%
"{" { return (L_LBRACE); }
"}" { return (L_RBRACE); }
";" { return (L_EOS); }
"options" { return (L_OPTIONS); }
"directory" { return (L_DIRECTORY); }
"zone" { return (L_ZONE); }
"type" { return (L_TYPE); }
"file" { return (L_FILE); }
"master" { return (L_MASTER); }
"slave" { return (L_SLAVE); }
"hint" { return (L_HINT); }
"stub" { return (L_STUB); }
"forward" { return (L_FORWARD); }
{intnum} {
yylval.num = strtol(yytext, NULL, 10);
return (L_INTEGER);
}
{qstring} {
yylval.cp = strdup(yytext + 1); /* skip open quote */
if (yylval.cp[yyleng - 2] != '"') {
/* XXX use an isc log function. */
fprintf(stderr, "Unterminated string");
} else {
yylval.cp[yyleng - 2] = '\0';
return L_QSTRING;
}
}
options {
directory "/var/named";
};
zone "vix.com" {
type master;
file "whatever";
};
/*
* Copyright (C) 1998, 1999 Internet Software Consortium.
*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
/*****
***** Module Info
*****/
/*
* Parser
*
* The parser module handles the parsing of config files.
*
* MP:
* Only a single thread is let through the modules at once.
* access.
*
* Reliability:
* No anticipated impact.
*
* Resources:
* <TBS>
*
* Security:
* <TBS>
*
* Standards:
* None.
*/
/***
*** Imports
***/
#include <config.h>
#include "configctx.h"
/***
*** Functions
***/
isc_result_t
isc_parser_init(void);
/*
* Does parser intitialization. Must be called before
* isc_parse_configuration() is called
*
* Requires:
* The caller do necessary locking to prevent multiple threads from
* calling it at once.
*
* Ensures:
* Nothing.
*
* Returns:
* ISC_R_SUCCESS
* ISC_R_FAILURE something broke
*/
isc_result_t
isc_parse_configuration(const char *filename,
isc_mem_t *mem,
isc_cfgctx_t **configctx);
/*
* Parse the confile file. Fills up the config context with the new config
* data. All memory allocations for the contents of configctx are done
* using the MEM argument.
*
* Requires:
* *filename is a valid filename.
* *mem is a valid memory manager.
* *configctx is a valid isc_config_ctx_t pointer
*
* Ensures:
* On success, *configctx is attached to the newly created config context.
*
* Returns:
* ISC_R_SUCCESS
* ISC_R_NOMEMORY
* ISC_R_INVALIDFILE file doesn't exist or is unreadable
* ISC_R_FAILURE file contains errors.
*/
%{
#if !defined(lint) && !defined(SABER)
static char rcsid[] = "$Id: parser.y,v 1.1 1999/01/30 00:50:10 brister Exp $";
#endif /* not lint */
/*
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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 <config.h>
#include <stdarg.h>
#include <stdio.h>
#include <isc/assertions.h>
#include <isc/mutex.h>
#include "parser.h"
#include "zone.h"
#include "configctx.h"
static int onetime ;
static isc_mutex_t yacc_mutex;
static isc_zonectx_t *currzonectx;
static isc_zoneinfo_t *currzone;
static isc_cfgctx_t *currcfg;
static const char *currfile;
static void parser_cleanup(void);
static void print_msg(char *fmt, va_list args);
static void parser_warning(char *fmt, ...);
static void parser_error(char *fmt, ...);
int yyparse(void);
void yyerror(const char *);
int yylex(void);
%}
%union {
char * cp;
long num;
isc_zonet_t ztype;
}
%token L_LBRACE
%token L_RBRACE
%token L_EOS
%token L_MASTER
%token L_SLAVE
%token L_HINT
%token L_STUB
%token L_FORWARD
/* options statement */
%token L_OPTIONS
%token L_DIRECTORY
/* Zone statements */
%token L_ZONE
%type <ztype> zone_type
%token L_TYPE
%token L_FILE
/* Misc */
%token <cp> L_STRING
%token <cp> L_QSTRING
%token <num> L_INTEGER
%%
config_file: statement_list
{
/* XXX Do post-read validations etc. */
}
;
statement_list: statement
| statement_list statement
;
statement: options_stmt L_EOS
| zone L_EOS
;
options_stmt: L_OPTIONS L_LBRACE options_list L_RBRACE
;
options_list: option L_EOS
| options_list option L_EOS
;
option: /* Empty */
| L_DIRECTORY L_QSTRING
{
printf("doing the option\n");
if (isc_cfg_setdirectory(currcfg, $2) != ISC_R_SUCCESS) {
parser_cleanup();
fprintf(stderr, "setdirectory error\n");
return (1);
}
}
;
zone: L_ZONE L_QSTRING
{
isc_zoneinfo_t *zi = NULL;
if (isc_zone_newinfo(currzonectx, &zi) != ISC_R_SUCCESS) {
parser_cleanup();
fprintf(stderr, "newzone error\n");
return (1);
}
isc_zone_setorigin(zi, $2);
currzone = zi;
} optional_zone_options_list {
/* XXX install zone if parsed correctly and remove
it if not. */
}
;
optional_zone_options_list: /* Empty */
| L_LBRACE zone_option_list L_RBRACE
;
zone_option_list: zone_option L_EOS
| zone_option_list zone_option L_EOS
;
zone_option: L_TYPE zone_type
{
}
| L_FILE L_QSTRING
{
INSIST(currzone != NULL);
if (currzone->source != NULL) {
parser_warning("zone filename already set; skipping");
} else {
isc_zone_setsource(currzone, $2);
}
}
;
zone_type: L_MASTER
{
$$ = zone_master;
}
| L_SLAVE
{
$$ = zone_slave;
}
| L_HINT
{
$$ = zone_hint;
}
| L_STUB
{
$$ = zone_stub;
}
| L_FORWARD
{
$$ = zone_forward;
}
;
%%
isc_result_t
isc_parser_init()
{
isc_result_t res = ISC_R_SUCCESS;
if (onetime == 0) {
/* our caller is locking us */
res = isc_mutex_init(&yacc_mutex);
onetime++;
}
return (res);
}
isc_result_t
isc_parse_configuration(const char *filename,
isc_mem_t *mem,
isc_cfgctx_t **configctx) {
isc_result_t res ;
isc_result_t t;
FILE *fp;
extern FILE *yyin;
/* Take out mutex on whole parser. */
if (isc_mutex_lock(&yacc_mutex) != ISC_R_SUCCESS) {
return (ISC_R_UNEXPECTED);
}
INSIST(currcfg == NULL);
if ((res = isc_cfg_newctx(mem, &currcfg)) != ISC_R_SUCCESS) {
isc_mutex_unlock(&yacc_mutex);
return (res);
}
if ((fp = fopen(filename, "r")) == NULL) {
isc_mutex_unlock(&yacc_mutex);
return (ISC_R_INVALIDFILE);
}
yyin = fp ;
currfile = filename;
currzonectx = currcfg->zonecontext;
if (yyparse() != 0) {
res = ISC_R_FAILURE;
}
fclose(fp);
*configctx = currcfg;
currcfg = NULL;
if ((t = isc_mutex_unlock(&yacc_mutex)) != ISC_R_SUCCESS) {
res = t;
}