aboutsummaryrefslogtreecommitdiff
path: root/src/meta1gram.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/meta1gram.y')
-rw-r--r--src/meta1gram.y395
1 files changed, 165 insertions, 230 deletions
diff --git a/src/meta1gram.y b/src/meta1gram.y
index 4966634..db92d61 100644
--- a/src/meta1gram.y
+++ b/src/meta1gram.y
@@ -1,6 +1,6 @@
%{
-/* MeTA1 configuration parser for Mailfromd.
- Copyright (C) 2008 Sergey Poznyakoff
+/* MeTA1 configuration parser for Pies.
+ Copyright (C) 2008, 2009 Sergey Poznyakoff
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,99 +22,98 @@
#include "pies.h"
#include "meta1lex.h"
-/* FIXME: Use mu_opool_alloc? */
-static mu_config_value_t *
-create_value (int type)
+#define META1_QUEUE_DIR() \
+ (meta1_queue_dir ? meta1_queue_dir : "/var/spool/meta1")
+
+enum meta1_stmt_type
+{
+ meta1_simple,
+ meta1_block
+};
+
+struct meta1_stmt
+{
+ struct meta1_stmt *next;
+ grecs_locus_t locus;
+ enum meta1_stmt_type type;
+ const char *ident;
+ union
+ {
+ grecs_value_t *value;
+ struct meta1_stmt *list;
+ } v;
+};
+
+struct meta1_stmt *
+meta1_stmt_create (enum meta1_stmt_type type, const char *ident)
{
- mu_config_value_t *val = mu_alloc (sizeof (*val));
- val->type = type;
- return val;
+ struct meta1_stmt *p = xmalloc (sizeof (*p));
+ p->next = NULL;
+ p->type = type;
+ p->ident = ident;
+ p->locus = meta1_locus;
+ return p;
}
-static mu_config_value_t *
-config_value_dup (mu_config_value_t *src)
+static struct meta1_stmt *
+_reverse (struct meta1_stmt *list, struct meta1_stmt **root)
{
- if (!src)
- return NULL;
- else
+ struct meta1_stmt *next;
+
+ if (list->next == NULL)
{
- mu_config_value_t *val = mu_alloc (sizeof (*val));
- *val = *src;
- return val;
+ *root = list;
+ return list;
}
+ next = _reverse (list->next, root);
+ next->next = list;
+ list->next = NULL;
+ return list;
}
-
-static mu_cfg_node_t *
-alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
- const char *tag, mu_config_value_t *label,
- mu_cfg_node_t *node)
+
+static struct meta1_stmt *
+reverse (struct meta1_stmt *in)
{
- char *p;
- mu_cfg_node_t *np;
- size_t size = sizeof *np + strlen (tag) + 1;
- np = mu_alloc (size);
- np->type = type;
- np->locus = *loc;
- p = (char*) (np + 1);
- np->tag = p;
- strcpy (p, tag);
- np->label = label;
- np->node = node;
- np->next = NULL;
- return np;
+ struct meta1_stmt *root;
+ if (!in)
+ return in;
+ _reverse (in, &root);
+ return root;
}
-static mu_cfg_node_t *translate_component (mu_cfg_node_t *);
-
-mu_cfg_node_t *meta1_parse_head;
-
+static void meta1_translate (struct meta1_stmt *);
%}
%union {
- mu_cfg_node_t node;
- mu_cfg_node_t *pnode;
- mu_config_value_t *value;
- struct { mu_cfg_node_t *head, *tail; } nodelist;
char *string;
- unsigned long number;
- mu_list_t list;
+ gl_list_t list;
+ grecs_value_t *value;
+ struct meta1_stmt *stmt;
}
%token <string> META1_IDENT META1_STRING META1_NUMBER
-
-%type <nodelist> stmtlist
-%type <pnode> stmt simple block
-%type <list> slist list values
+%type <list> slist values list
+%type <value> value
%type <string> string ident
-%type <value> value
-
+%type <stmt> stmtlist stmt simple block
%%
input : stmtlist
{
- mu_cfg_node_t *node;
- meta1_parse_head = NULL;
- for (node = $1.head; node; node = node->next)
- {
- mu_cfg_node_t *new_node = translate_component (node);
- if (new_node)
- {
- new_node->next = meta1_parse_head;
- meta1_parse_head = new_node;
- }
- }
+ struct meta1_stmt *stmt;
+ for (stmt = $1; stmt; stmt = stmt->next)
+ meta1_translate (stmt);
}
;
stmtlist: stmt
{
- $$.head = $$.tail = $1;
+ $$ = $1;
}
| stmtlist stmt
{
- $$ = $1;
- $$.tail->next = $2;
- $$.tail = $2;
+ $2->next = $1;
+ $$ = $2;
}
;
@@ -124,18 +123,15 @@ stmt : simple
simple : ident '=' value opt_sc
{
- $$ = alloc_node (mu_cfg_node_param, &meta1_locus,
- $1, $3,
- NULL);
+ $$ = meta1_stmt_create (meta1_simple, $1);
+ $$->v.value = $3;
}
;
block : ident tag '{' stmtlist '}' opt_sc
- {
- /* FIXME: tag is currently ignored */
- $$ = alloc_node (mu_cfg_node_tag, &meta1_locus,
- $1, NULL,
- $4.head);
+ {
+ $$ = meta1_stmt_create (meta1_block, $1);
+ $$->v.list = reverse ($4);
}
;
@@ -148,49 +144,50 @@ ident : META1_IDENT
value : string
{
- $$ = create_value (MU_CFG_STRING);
+ $$ = xmalloc (sizeof (*$$));
+ $$->type = GRECS_TYPE_STRING;
$$->v.string = $1;
}
| list
{
- $$ = create_value (MU_CFG_LIST);
+ $$ = xmalloc (sizeof (*$$));
+ $$->type = GRECS_TYPE_LIST;
$$->v.list = $1;
}
| META1_NUMBER
{
- $$ = create_value (MU_CFG_STRING);
+ $$ = xmalloc (sizeof (*$$));
+ $$->type = GRECS_TYPE_STRING;
$$->v.string = $1;
- }
+ }
;
string : META1_IDENT
| slist
{
- mu_iterator_t itr;
- mu_list_get_iterator ($1, &itr);
+ const void *p;
+ gl_list_iterator_t itr = gl_list_iterator ($1);
meta1_line_begin ();
- for (mu_iterator_first (itr);
- !mu_iterator_is_done (itr); mu_iterator_next (itr))
- {
- char *p;
- mu_iterator_current (itr, (void**)&p);
- meta1_line_add (p, strlen (p));
- }
+ while (gl_list_iterator_next (&itr, &p, NULL))
+ meta1_line_add (p, strlen (p));
+ gl_list_iterator_free (&itr);
$$ = meta1_line_finish ();
- mu_iterator_destroy (&itr);
- mu_list_destroy (&$1);
}
;
slist : META1_STRING
{
- mu_list_create (&$$);
- mu_list_append ($$, $1);
+ $$ = gl_list_create_empty (&gl_linked_list_implementation,
+ NULL,
+ NULL,
+ NULL,
+ true);
+ gl_list_add_last ($$, $1);
}
| slist META1_STRING
{
- mu_list_append ($1, $2);
+ gl_list_add_last ($1, $2);
$$ = $1;
}
;
@@ -207,12 +204,16 @@ list : '{' values '}'
values : value
{
- mu_list_create (&$$);
- mu_list_append ($$, $1);
+ $$ = gl_list_create_empty (&gl_linked_list_implementation,
+ NULL,
+ NULL,
+ NULL,
+ true);
+ gl_list_add_last ($$, $1);
}
| values ',' value
{
- mu_list_append ($1, $3);
+ gl_list_add_last ($1, $3);
$$ = $1;
}
;
@@ -232,19 +233,27 @@ yyerror (char *s)
void
meta1_parser_set_debug ()
{
- mu_log_level_t lev = mu_global_debug_level ("meta1");
- if (lev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE6))
- yydebug = 1;
+ char *p = getenv ("META1_DEBUG_YACC");
+ yydebug = p && (*p - '0') > 0;
}
+static struct meta1_stmt *
+find_stmt (struct meta1_stmt *stmt, const char *ident)
+{
+ for (; stmt; stmt = stmt->next)
+ if (strcmp (stmt->ident, ident) == 0)
+ break;
+ return stmt;
+}
+
+
struct node_trans
{
char *name;
char *new_name;
- mu_cfg_node_t *(*fun) (const char *, mu_cfg_node_t *);
+ int (*xlat) (struct meta1_stmt *stmt, struct component *comp);
};
-
static struct node_trans *
find_node_trans (struct node_trans *tab, const char *name)
{
@@ -254,54 +263,43 @@ find_node_trans (struct node_trans *tab, const char *name)
return NULL;
}
-static mu_cfg_node_t *
-find_node (mu_cfg_node_t *list, const char *name)
-{
- for (; list; list = list->next)
- {
- if (strcmp (list->tag, name) == 0)
- return list;
- }
- return NULL;
-}
-
-static mu_cfg_node_t *
-xlat_listen_socket (const char *name, mu_cfg_node_t *src)
+static int
+xlat_listen_socket (struct meta1_stmt *stmt, struct component *comp)
{
- mu_cfg_node_t *p;
- mu_config_value_t *val;
+ struct meta1_stmt *p;
+ grecs_value_t *val;
+ p = find_stmt (stmt->v.list, "type");
+ if (!p || !p->v.value || p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
meta1_line_begin ();
- p = find_node (src->node, "type");
- if (!p || !p->label || p->label->type != MU_CFG_STRING)
- return NULL;
- meta1_line_add (p->label->v.string, strlen (p->label->v.string));
+ meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
meta1_line_add ("://", 3);
- if (strcmp (p->label->v.string, "inet") == 0)
+ if (strcmp (p->v.value->v.string, "inet") == 0)
{
const char *addr;
- p = find_node (src->node, "address");
+ p = find_stmt (stmt->v.list, "address");
if (p)
{
- if (p->label->type != MU_CFG_STRING)
- return NULL;
- addr = p->label->v.string;
+ if (p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
+ addr = p->v.value->v.string;
}
else
addr = "0.0.0.0";
meta1_line_add (addr, strlen (addr));
meta1_line_add (":", 1);
- p = find_node (src->node, "port");
- if (p->label->type != MU_CFG_STRING)
- return NULL;
- meta1_line_add (p->label->v.string, strlen (p->label->v.string));
+ p = find_stmt (stmt->v.list, "port");
+ if (p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
+ meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
}
- else if (strcmp (p->label->v.string, "unix") == 0)
+ else if (strcmp (p->v.value->v.string, "unix") == 0)
{
- p = find_node (src->node, "path");
- if (!p || p->label->type != MU_CFG_STRING)
- return NULL;
- meta1_line_add (p->label->v.string, strlen (p->label->v.string));
+ p = find_stmt (stmt->v.list, "path");
+ if (!p || p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
+ meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
/* FIXME: Other substatements:
listen_socket {
type=unix;
@@ -312,11 +310,15 @@ xlat_listen_socket (const char *name, mu_cfg_node_t *src)
}
*/
}
- val = create_value (MU_CFG_STRING);
+ val = xmalloc (sizeof (*val));
+ val->type = GRECS_TYPE_STRING;
val->v.string = meta1_line_finish ();
- return alloc_node (mu_cfg_node_param, &src->locus, "socket", val, NULL);
+ stmt->type = meta1_simple;
+ stmt->v.value = val;
+ return 0;
}
+
static struct node_trans root_node_trans[] = {
{ "listen_socket", "socket", xlat_listen_socket },
{ "start_action", "mode" },
@@ -328,112 +330,45 @@ static struct node_trans root_node_trans[] = {
{ NULL }
};
-static mu_cfg_node_t *
-create_string_node (const char *tag, const char *str, mu_cfg_locus_t *locus)
+static void
+meta1_translate_stmt (struct meta1_stmt *stmt, struct component *comp)
{
- mu_config_value_t *val = create_value (MU_CFG_STRING);
+ struct grecs_keyword *kwp;
- val->v.string = meta1_string (str, strlen (str));
- return alloc_node (mu_cfg_node_param, locus, tag, val, NULL);
-}
-
-static mu_cfg_node_t *
-create_redir_node (const char *tag, const char *dir,
- const char *name, mu_cfg_locus_t *locus)
-{
- mu_config_value_t *val = create_value (MU_CFG_ARRAY);
- val->v.arg.c = 2;
- val->v.arg.v = mu_alloc (2 * sizeof (val->v.arg.v[0]));
+ struct node_trans *nt = find_node_trans (root_node_trans, stmt->ident);
+ if (!nt)
+ return;
- val->v.arg.v[1].type = MU_CFG_STRING;
- val->v.arg.v[0].v.string = meta1_string ("file", 4);
+ kwp = find_component_keyword (nt->new_name);
+ if (!kwp)
+ abort ();
- val->v.arg.v[1].type = MU_CFG_STRING;
- meta1_line_begin ();
- meta1_line_add (dir, strlen (dir));
- meta1_line_add ("/", 1);
- meta1_line_add (name, strlen (name));
- meta1_line_add (".log", 4);
- val->v.arg.v[1].v.string = meta1_line_finish ();
+ if (nt->xlat && nt->xlat (stmt, comp))
+ return;
- return alloc_node (mu_cfg_node_param, locus, tag, val, NULL);
+ grecs_process_ident (kwp, stmt->v.value, comp, &stmt->locus);
}
-static mu_cfg_node_t *
-translate_node (mu_cfg_node_t *src)
+static void
+meta1_translate (struct meta1_stmt *stmt)
{
- mu_cfg_node_t *dst = NULL;
- struct node_trans *nt = find_node_trans (root_node_trans, src->tag);
+ struct component *comp;
+ struct meta1_stmt *p;
- if (nt)
- {
- if (nt->fun)
- dst = nt->fun (nt->new_name, src);
- else
- dst = alloc_node (mu_cfg_node_param, &src->locus,
- nt->new_name, config_value_dup (src->label),
- NULL);
- }
- return dst;
-}
-
-#define META1_QUEUE_DIR() \
- (meta1_queue_dir ? meta1_queue_dir : "/var/spool/meta1")
-
-static mu_cfg_node_t *
-translate_node_list (mu_cfg_node_t *src, const char *name)
-{
- mu_cfg_node_t *head = NULL, *tail = NULL;
- mu_cfg_locus_t *locus = &src->locus;
+ if (stmt->type != meta1_block)
+ return;
- for (; src; src = src->next)
- {
- mu_cfg_node_t *dst = translate_node (src);
- if (dst)
- {
- if (tail)
- tail->next = dst;
- else
- head = dst;
- tail = dst;
- }
- }
- if (head)
+ comp = component_create (stmt->ident);
+ for (p = stmt->v.list; p; p = p->next)
{
- /* Add common statements: */
- mu_cfg_node_t *node;
-
- node = create_string_node ("allgroups", "yes", locus);
- tail->next = node;
- tail = node;
-
- node = create_string_node ("chdir", META1_QUEUE_DIR (), locus);
- tail->next = node;
- tail = node;
-
- node = create_redir_node ("stderr", META1_QUEUE_DIR (), name, locus);
- tail->next = node;
- tail = node;
-
- node = create_string_node ("settle-timeout", "1", locus);
- tail->next = node;
- tail = node;
+ meta1_translate_stmt (p, comp);
}
- return head;
+ comp->privs.allgroups = 1;
+ comp->dir = META1_QUEUE_DIR ();
+ comp->settle_timeout = 1;
+ comp->redir[RETR_ERR].type = redir_file;
+ comp->redir[RETR_ERR].v.file = xasprintf ("%s/%s.log",
+ META1_QUEUE_DIR (),
+ comp->tag);
+ component_finish (comp, &stmt->locus);
}
-
-static mu_cfg_node_t *
-translate_component (mu_cfg_node_t *src)
-{
- mu_cfg_node_t *dst = NULL;
- if (src->type == mu_cfg_node_tag)
- {
- mu_config_value_t *val = create_value (MU_CFG_STRING);
- val->v.string = meta1_string (src->tag, strlen (src->tag));
- dst = alloc_node (mu_cfg_node_tag, &src->locus,
- "component", val,
- translate_node_list (src->node, val->v.string));
- }
- return dst;
-}
-

Return to:

Send suggestions and report system problems to the System administrator.