summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org>2016-01-09 11:54:55 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2016-01-09 11:58:20 (GMT)
commit61cc2fe261b24ec3a5f2a21d76fd331711cb84f4 (patch) (side-by-side diff)
treedce35e194199a0006d8b01d6ecf620c6cf99c3a9
parent7361c5a48968685f1ac6bb8561072b2dfe6a5a61 (diff)
downloadpies-61cc2fe261b24ec3a5f2a21d76fd331711cb84f4.tar.gz
pies-61cc2fe261b24ec3a5f2a21d76fd331711cb84f4.tar.bz2
Use grecs meta1 parser
* configure.ac (GRECS_SETUP): Require parser-meta1 * grecs: Upgrade. * po/POTFILES.in: Update. * src/Makefile.am: Remove meta1gram.y and meta1lex.l Add meta1parse.c and meta1parse.h * src/meta1gram.y: Remove. * src/meta1lex.l: Remove. * src/meta1parse.c: New file. * src/meta1parse.h: New file. * src/pies.c: Include meta1parse.h instead of meta1lex.h
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--configure.ac2
m---------grecs0
-rw-r--r--po/POTFILES.in5
-rw-r--r--src/Makefile.am11
-rw-r--r--src/meta1gram.y406
-rw-r--r--src/meta1lex.l232
-rw-r--r--src/meta1parse.c360
-rw-r--r--src/meta1parse.h3
-rw-r--r--src/pies.c2
9 files changed, 370 insertions, 651 deletions
diff --git a/configure.ac b/configure.ac
index 114fc07..b99f6f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,7 +72,7 @@ AC_CHECK_FUNCS([alarm dup2 gethostbyname memmove memset select setenv socket str
gl_INIT
# Grecs
-GRECS_SETUP([grecs],[tests git2chg getopt json sockaddr-list])
+GRECS_SETUP([grecs],[tests git2chg getopt json sockaddr-list parser-meta1])
GRECS_HOST_PROJECT_INCLUDES='-I$(top_srcdir)/gnu -I$(top_builddir)/gnu'
# Test for setproctitle
diff --git a/grecs b/grecs
-Subproject 3df291f812208a8ce07a2878784a0a73e458719
+Subproject ca94270a5e30add9b364d32220fb38d457ebd3f
diff --git a/po/POTFILES.in b/po/POTFILES.in
index acc6127..6e62a76 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -17,12 +17,13 @@
src/acl.c
lib/addrfmt.c
+src/ctl.c
src/depmap.c
src/diag.c
src/limits.c
-src/meta1gram.y
-src/meta1lex.l
+src/meta1parse.c
src/pies.c
+src/piesctl.c
src/progman.c
src/socket.c
lib/url.c
diff --git a/src/Makefile.am b/src/Makefile.am
index a2400fb..3f29b4e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,8 +25,7 @@ pies_SOURCES = \
inetd.c\
inetd-bi.c\
limits.c\
- meta1gram.y\
- meta1lex.l\
+ meta1parse.c\
pies.c\
progman.c\
socket.c\
@@ -38,14 +37,11 @@ pies_SOURCES = \
noinst_HEADERS = \
acl.h\
cmdline.h\
- meta1gram.h\
- meta1lex.h\
+ meta1parse.h\
pies.h\
prog.h\
piesctl-cl.h
-meta1lex.c: meta1gram.h
-
BUILT_SOURCES=cmdline.h piesctl-cl.h
incdir=$(pkgdatadir)/$(VERSION)/include
@@ -89,9 +85,6 @@ AM_CPPFLAGS=\
-DDEFAULT_PIES_CONTROL_URL='"$(DEFAULT_PIES_CONTROL_URL)"'\
-DDEFAULT_INIT_CONTROL_URL='"$(DEFAULT_INIT_CONTROL_URL)"'
-AM_YFLAGS=-dvt -pmeta1
-AM_LFLAGS=-dvp -Pmeta1 -olex.yy.c
-
EXTRA_SCRIPTS = inetd
sbin_SCRIPTS = @INETD@
diff --git a/src/meta1gram.y b/src/meta1gram.y
deleted file mode 100644
index 3e19a12..0000000
--- a/src/meta1gram.y
+++ b/dev/null
@@ -1,406 +0,0 @@
-%{
-/* MeTA1 configuration parser for GNU Pies.
- Copyright (C) 2008, 2009, 2010, 2011, 2013 Sergey Poznyakoff
-
- GNU Pies is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GNU Pies is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
-
-/* This file implements a grammar for parsing MeTA1 main configuration file,
- and a set of functions for converting its statements into Pies
- configuration statements. */
-
-#include "pies.h"
-#include "grecs-locus.h"
-#include "meta1lex.h"
-#include "meta1gram.h"
-
-#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)
-{
- struct meta1_stmt *p = grecs_malloc (sizeof (*p));
- p->next = NULL;
- p->type = type;
- p->ident = ident;
- p->locus = meta1lloc;
- return p;
-}
-
-static struct meta1_stmt *
-_reverse (struct meta1_stmt *list, struct meta1_stmt **root)
-{
- struct meta1_stmt *next;
-
- if (list->next == NULL)
- {
- *root = list;
- return list;
- }
- next = _reverse (list->next, root);
- next->next = list;
- list->next = NULL;
- return list;
-}
-
-static struct meta1_stmt *
-reverse (struct meta1_stmt *in)
-{
- struct meta1_stmt *root;
- if (!in)
- return in;
- _reverse (in, &root);
- return root;
-}
-
-static void meta1_translate (struct meta1_stmt *);
-%}
-
-%error-verbose
-%locations
-
-%union {
- char *string;
- struct grecs_list *list;
- grecs_value_t *value;
- struct meta1_stmt *stmt;
-}
-
-%token <string> META1_IDENT META1_STRING META1_NUMBER
-%type <list> slist values list
-%type <value> value
-%type <string> string ident tag
-%type <stmt> stmtlist stmt simple block
-%%
-
-input : stmtlist
- {
- struct meta1_stmt *stmt;
- for (stmt = $1; stmt; stmt = stmt->next)
- meta1_translate (stmt);
- }
- ;
-
-stmtlist: stmt
- {
- $$ = $1;
- }
- | stmtlist stmt
- {
- $2->next = $1;
- $$ = $2;
- }
- ;
-
-stmt : simple
- | block
- ;
-
-simple : ident '=' value opt_sc
- {
- $$ = meta1_stmt_create (meta1_simple, $1);
- $$->v.value = $3;
- }
- ;
-
-block : ident tag '{' stmtlist '}' opt_sc
- {
- $$ = meta1_stmt_create (meta1_block, $2 ? $2 : $1);
- $$->v.list = reverse ($4);
- }
- ;
-
-tag : /* empty */
- {
- $$ = NULL;
- }
- | META1_IDENT
- ;
-
-ident : META1_IDENT
- ;
-
-value : string
- {
- $$ = grecs_malloc (sizeof (*$$));
- $$->type = GRECS_TYPE_STRING;
- $$->v.string = $1;
- }
- | list
- {
- $$ = grecs_malloc (sizeof (*$$));
- $$->type = GRECS_TYPE_LIST;
- $$->v.list = $1;
- }
- | META1_NUMBER
- {
- $$ = grecs_malloc (sizeof (*$$));
- $$->type = GRECS_TYPE_STRING;
- $$->v.string = $1;
- }
- ;
-
-string : META1_IDENT
- | slist
- {
- struct grecs_list_entry *ep;
- meta1_line_begin ();
- for (ep = $1->head; ep; ep = ep->next)
- {
- const char *p = ep->data;
- meta1_line_add (p, strlen (p));
- }
- $$ = meta1_line_finish ();
- }
- ;
-
-slist : META1_STRING
- {
- $$ = grecs_list_create ();
- grecs_list_append ($$, $1);
- }
- | slist META1_STRING
- {
- grecs_list_append ($1, $2);
- $$ = $1;
- }
- ;
-
-list : '{' values '}'
- {
- $$ = $2;
- }
- | '{' values ',' '}'
- {
- $$ = $2;
- }
- ;
-
-values : value
- {
- $$ = grecs_list_create ();
- grecs_list_append ($$, $1);
- }
- | values ',' value
- {
- grecs_list_append ($1, $3);
- $$ = $1;
- }
- ;
-
-opt_sc : /* empty */
- | ';'
- ;
-
-%%
-int
-yyerror (char const *s)
-{
- grecs_error (&yylloc, 0, "%s", s);
- return 0;
-}
-
-void
-meta1_parser_set_debug ()
-{
- 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;
- int (*xlat) (struct meta1_stmt *stmt, struct component *comp);
-};
-
-static struct node_trans *
-find_node_trans (struct node_trans *tab, const char *name)
-{
- for (; tab->name; tab++)
- if (strcmp (tab->name, name) == 0)
- return tab;
- return NULL;
-}
-
-static int
-xlat_listen_socket (struct meta1_stmt *stmt, struct component *comp)
-{
- 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 ();
- meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
- meta1_line_add ("://", 3);
- if (strcmp (p->v.value->v.string, "inet") == 0)
- {
- const char *addr;
- p = find_stmt (stmt->v.list, "address");
- if (p)
- {
- 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_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->v.value->v.string, "unix") == 0)
- {
- /* listen_socket {
- type=unix;
- path = /tmp/socket;
- umask = 077;
- user = user;
- group = group;
- }
- */
- 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));
-
- p = find_stmt (stmt->v.list, "user");
- if (p && p->v.value->type == GRECS_TYPE_STRING)
- {
- meta1_line_add (";user=", 6);
- meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
- }
-
- p = find_stmt (stmt->v.list, "group");
- if (p && p->v.value->type == GRECS_TYPE_STRING)
- {
- meta1_line_add (";group=", 7);
- meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
- }
-
- p = find_stmt (stmt->v.list, "umask");
- if (p && p->v.value->type == GRECS_TYPE_STRING)
- {
- meta1_line_add (";umask=", 7);
- meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
- }
- }
- val = grecs_malloc (sizeof (*val));
- val->type = GRECS_TYPE_STRING;
- val->v.string = meta1_line_finish ();
- stmt->type = meta1_simple;
- stmt->v.value = val;
- return 0;
-}
-
-static int
-xlat_start_action (struct meta1_stmt *stmt, struct component *comp)
-{
- if (strcmp (stmt->v.value->v.string, "wait") == 0)
- {
- meta1_line_begin ();
- meta1_line_add ("exec", 4);
- stmt->v.value->v.string = meta1_line_finish ();
- }
- return 0;
-}
-
-static struct node_trans root_node_trans[] = {
- { "listen_socket", "socket", xlat_listen_socket },
- { "start_action", "mode", xlat_start_action },
- { "pass_fd_socket", "pass-fd-socket" },
- { "user", "user" },
- { "path", "program" },
- { "arguments", "command" },
- { "restart_dependencies", "dependents", },
- { NULL }
-};
-
-static void
-meta1_translate_stmt (struct meta1_stmt *stmt, struct component *comp)
-{
- struct grecs_keyword *kwp;
-
- struct node_trans *nt = find_node_trans (root_node_trans, stmt->ident);
- if (!nt)
- return;
-
- kwp = find_component_keyword (nt->new_name);
- if (!kwp)
- abort ();
-
- if (nt->xlat && nt->xlat (stmt, comp))
- return;
-
- grecs_process_ident (kwp, stmt->v.value, comp, &stmt->locus);
-}
-
-static void
-meta1_translate (struct meta1_stmt *stmt)
-{
- struct component *comp;
- struct meta1_stmt *p;
- size_t len;
-
- if (stmt->type != meta1_block)
- return;
-
- comp = component_create (stmt->ident);
- for (p = stmt->v.list; p; p = p->next)
- {
- meta1_translate_stmt (p, comp);
- }
- comp->privs.allgroups = 1;
- comp->dir = META1_QUEUE_DIR ();
- comp->redir[RETR_ERR].type = redir_file;
- comp->redir[RETR_ERR].v.file = NULL;
- len = 0;
- grecs_asprintf (&comp->redir[RETR_ERR].v.file, &len,
- "%s/%s.log", META1_QUEUE_DIR (), comp->tag);
- component_finish (comp, &stmt->locus);
-}
diff --git a/src/meta1lex.l b/src/meta1lex.l
deleted file mode 100644
index a074a8d..0000000
--- a/src/meta1lex.l
+++ b/dev/null
@@ -1,232 +0,0 @@
-/* MeTA1 configuration lexer for GNU Pies. -*- c -*- */
-%option nounput
-%option noinput
-%top {
-/* MeTA1 configuration lexer for GNU Pies.
- Copyright (C) 2008, 2009, 2010, 2011, 2013 Sergey Poznyakoff
-
- GNU Pies is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GNU Pies is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
-
-/* This file implements a lexical analyzer for MeTA1 main configuration file.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-}
-
-%{
-#include "pies.h"
-#include "grecs-locus.h"
-#include "meta1gram.h"
-#include "meta1lex.h"
-
-static struct grecs_locus_point meta1_locus_point;
-static struct grecs_txtacc *meta1_txtacc;
-char *meta1_queue_dir;
-#define yylval meta1lval
-
-#define YY_USER_ACTION do \
- { \
- if (YYSTATE == 0) \
- { \
- meta1lloc.beg = meta1_locus_point; \
- meta1lloc.beg.col++; \
- } \
- meta1_locus_point.col += yyleng; \
- meta1lloc.end = meta1_locus_point; \
- } \
- while (0);
-%}
-
-%x COMMENT STR
-X [0-9a-fA-F]
-%%
- /* C-style comments */
-"/*" BEGIN (COMMENT);
-<COMMENT>[^*\n]* /* eat anything that's not a '*' */
-<COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
-<COMMENT>\n grecs_locus_point_advance_line(meta1_locus_point);
-<COMMENT>"*"+"/" BEGIN (INITIAL);
- /* End-of-line comments */
-#.*\n grecs_locus_point_advance_line(meta1_locus_point);
-#.* /* end-of-file comment */;
- /* Number */
-0[xX]{X}+ |
-0[0-7]+ |
-[1-9][0-9]+ { meta1_line_begin ();
- meta1_line_add (yytext, yyleng);
- yylval.string = meta1_line_finish ();
- return META1_NUMBER; }
- /* Identifiers (unquoted strings) */
-[a-zA-Z0-9_\./:\*-]+ { meta1_line_begin ();
- meta1_line_add (yytext, yyleng);
- yylval.string = meta1_line_finish ();
- return META1_IDENT; }
- /* Quoted strings */
-\"[^\\"\n]*\" { meta1_line_begin ();
- meta1_line_add (yytext + 1, yyleng - 2);
- yylval.string = meta1_line_finish ();
- return META1_STRING; }
-\"[^\\"\n]*\\x{X}{1,2} { BEGIN(STR);
- meta1_line_begin ();
- meta1_line_add_unescape_hex (yytext + 1, yyleng - 1);
- }
-\"[^\\"\n]*\\. { BEGIN(STR);
- meta1_line_begin ();
- meta1_line_add_unescape_last (yytext + 1, yyleng - 1); }
-<STR>[^\\"\n]*\\x{X}{1,2} { meta1_line_add_unescape_hex (yytext, yyleng); }
-<STR>[^\\"\n]*\\. { meta1_line_add_unescape_last (yytext, yyleng); }
-<STR>[^\\"\n]*\" { BEGIN (INITIAL);
- if (yyleng > 1)
- meta1_line_add (yytext, yyleng - 1);
- yylval.string = meta1_line_finish ();
- return META1_STRING; }
-<STR>[^\\"\n]*\n { BEGIN (INITIAL);
- grecs_error (&meta1lloc, 0, _("newline in a string"));
- meta1_line_add (yytext, yyleng - 1);
- yylval.string = meta1_line_finish ();
- return META1_STRING; }
- /* Other tokens */
-[ \t\f][ \t\f]* ;
-\n grecs_locus_point_advance_line(meta1_locus_point);
-[,;{}=] return yytext[0];
-. { if (isascii (yytext[0]) && isprint (yytext[0]))
- grecs_error (&meta1lloc, 0, _("stray character %c"), yytext[0]);
- else
- grecs_error (&meta1lloc, 0, _("stray character \\%03o"),
- (unsigned char) yytext[0]); }
-%%
-
-int
-yywrap ()
-{
- return 1;
-}
-
-void
-meta1_line_add (const char *text, size_t len)
-{
- grecs_txtacc_grow (meta1_txtacc, text, len);
-}
-
-static char quote_transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
-
-static int
-unescape_char (int c)
-{
- char *p;
-
- for (p = quote_transtab; *p; p += 2)
- {
- if (*p == c)
- return p[1];
- }
- return c;
-}
-
-static void
-unescape_to_line (int c)
-{
- char t;
-
- if (c == 'v')
- t = '\v';
- else
- {
- t = unescape_char (c);
- if (t == c && t != '\\' && t != '\"')
- grecs_error (&meta1lloc, 0, _("unknown escape sequence '\\%c'"), c);
- }
- grecs_txtacc_grow_char (meta1_txtacc, t);
-}
-
-void
-meta1_line_add_unescape_last (const char *text, size_t len)
-{
- grecs_txtacc_grow (meta1_txtacc, text, len - 2);
- unescape_to_line (text[len - 1]);
-}
-
-void
-meta1_line_add_unescape_hex (const char *text, size_t len)
-{
- for (; text[len-1] != 'x' && len > 0; len--)
- ;
- grecs_txtacc_grow (meta1_txtacc, text, len - 2);
- grecs_txtacc_grow_char (meta1_txtacc, (char) strtoul (text + len, NULL, 16));
-}
-
-void
-meta1_line_begin ()
-{
- if (!meta1_txtacc)
- meta1_txtacc = grecs_txtacc_create();
-}
-
-char *
-meta1_line_finish ()
-{
- grecs_txtacc_grow_char (meta1_txtacc, 0);
- return grecs_txtacc_finish (meta1_txtacc, 0);
-}
-
-char *
-meta1_string (const char *str, size_t len)
-{
- meta1_line_begin ();
- meta1_line_add (str, len);
- return meta1_line_finish ();
-}
-
-void
-meta1_lexer_set_debug ()
-{
- char *p = getenv ("META1_DEBUG_LEX");
- yy_flex_debug = p && (*p - '0') > 0;
-}
-
-/* Parse MeTA1 configuration file `name'. Populate `meta1_parse_tree' with
- the parse tree. */
-int
-meta1_config_parse (const char *name)
-{
- int rc;
- FILE *fp;
-
- fp = fopen (name, "r");
- if (!fp)
- {
- logmsg (LOG_ERR,
- _("%s: cannot open file: %s"), name, strerror (errno));
- return 1;
- }
- meta1_locus_point.file = meta1_string (name, strlen (name));
- meta1_locus_point.line = 1;
- meta1_locus_point.col = 0;
- meta1_lexer_set_debug ();
- meta1_parser_set_debug ();
-
- yyrestart (fp);
- grecs_error_count = 0;
- rc = meta1parse ();
- fclose (fp);
- if (grecs_error_count)
- rc = 1;
- return rc;
-}
-
-
-
-
diff --git a/src/meta1parse.c b/src/meta1parse.c
new file mode 100644
index 0000000..059ea54
--- a/dev/null
+++ b/src/meta1parse.c
@@ -0,0 +1,360 @@
+/* This file is part of GNU Pies.
+ Copyright (C) 2016 Sergey Poznyakoff
+
+ GNU Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Pies is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "pies.h"
+
+char *meta1_queue_dir;
+
+#define META1_QUEUE_DIR() \
+ (meta1_queue_dir ? meta1_queue_dir : "/var/spool/meta1")
+
+static void
+setflag (int *flag, char const *var, int bit)
+{
+ char *p = getenv (var);
+ if (p && (*p - '0') > 0)
+ *flag |= bit;
+}
+
+
+static enum grecs_tree_recurse_res
+freeproc (enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
+{
+ switch (op)
+ {
+ case grecs_tree_recurse_set:
+ case grecs_tree_recurse_post:
+ grecs_node_unlink (node);
+ grecs_node_free (node);
+ break;
+ case grecs_tree_recurse_pre:
+ /* descend into the subtree */
+ break;
+ }
+ return grecs_tree_recurse_ok;
+}
+
+int
+grecs_subtree_free (struct grecs_node *node)
+{
+ if (!node)
+ return 0;
+ if (node->type != grecs_node_block)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+ grecs_tree_recurse (node, freeproc, node);
+ return 0;
+}
+
+
+static int
+xlat_start_action (struct grecs_node *node)
+{
+ if (node->type != grecs_node_stmt)
+ return -1;
+ if (strcmp (node->v.value->v.string, "wait") == 0)
+ {
+ node->v.value->v.string = grecs_strdup ("exec");
+ }
+ return 0;
+}
+
+enum substatement_status
+ {
+ substatement_success,
+ substatement_error,
+ substatement_not_found
+ };
+
+static struct grecs_node *
+simple_find_node (struct grecs_node *node, char const *name)
+{
+ for (node = node->down; node; node = node->next)
+ if (strcmp (node->ident, name) == 0)
+ break;
+ return node;
+}
+
+static enum substatement_status
+substatement_find (struct grecs_node *node, char const *name, int type,
+ int req, grecs_value_t **ret)
+{
+ struct grecs_node *np;
+
+ np = simple_find_node (node, name);
+ if (!np)
+ {
+ if (req)
+ grecs_error (&node->locus, 0, _("no \"%s\" statement in block"),
+ name);
+ return substatement_not_found;
+ }
+
+ if (node->type != grecs_node_block)
+ {
+ grecs_error (&node->locus, 0, _("unexpected scalar statement"));
+ return substatement_error;
+ }
+
+ if (assert_grecs_value_type (&np->v.value->locus, np->v.value, type))
+ return substatement_error;
+
+ *ret = np->v.value;
+
+ return substatement_success;
+}
+
+static int
+translate_url_param (struct grecs_node *node, char const *name,
+ struct grecs_txtacc *acc)
+{
+ struct grecs_value *np;
+
+ switch (substatement_find (node, name, GRECS_TYPE_STRING, 0, &np))
+ {
+ case substatement_success:
+ grecs_txtacc_grow_char (acc, ';');
+ grecs_txtacc_grow_string (acc, name + 1);
+ grecs_txtacc_grow_char (acc, '=');
+ grecs_txtacc_grow_string (acc, np->v.string);
+ break;
+
+ case substatement_not_found:
+ break;
+
+ case substatement_error:
+ return -1;
+ }
+ return 0;
+}
+
+static int
+xlat_listen_socket_i (struct grecs_node *node, char const *type,
+ struct grecs_txtacc *acc)
+{
+ struct grecs_value *val, *vp;
+ char *url;
+
+ grecs_txtacc_grow_string (acc, type);
+ grecs_txtacc_grow (acc, "://", 3);
+
+ if (strcmp (type, "inet") == 0)
+ {
+ const char *addr;
+
+ switch (substatement_find (node, "address", GRECS_TYPE_STRING, 0, &vp))
+ {
+ case substatement_success:
+ addr = vp->v.string;
+ break;
+
+ case substatement_not_found:
+ addr = "0.0.0.0";
+ break;
+
+ case substatement_error:
+ return -1;
+ }
+
+ grecs_txtacc_grow_string (acc, addr);
+ grecs_txtacc_grow_char (acc, ':');
+
+ if (substatement_find (node, "port", GRECS_TYPE_STRING, 1, &vp) !=
+ substatement_success)
+ return -1;
+ grecs_txtacc_grow_string (acc, vp->v.string);
+ }
+ else if (strcmp (type, "unix") == 0)
+ {
+ /* listen_socket {
+ type=unix;
+ path = /tmp/socket;
+ umask = 077;
+ user = user;
+ group = group;
+ }
+ */
+ if (substatement_find (node, "path", GRECS_TYPE_STRING, 1, &vp) !=
+ substatement_success)
+ return -1;
+
+ grecs_txtacc_grow_string (acc, vp->v.string);
+ if (translate_url_param (node, "user", acc))
+ return -1;
+ if (translate_url_param (node, "group", acc))
+ return -1;
+ if (translate_url_param (node, "umask", acc))
+ return -1;
+ }
+ else
+ {
+ grecs_error (&node->locus, 0, _("unsupported type"));
+ return -1;
+ }
+
+ grecs_txtacc_grow_char (acc, 0);
+ url = grecs_txtacc_finish (acc, 1);
+
+ val = grecs_malloc (sizeof(*val));
+ val->type = GRECS_TYPE_STRING;
+ val->locus = node->locus;
+ val->v.string = url;
+
+ grecs_subtree_free (node->down);
+
+ node->type = grecs_node_stmt;
+ node->v.value = val;
+ return 0;
+}
+
+static int
+xlat_listen_socket (struct grecs_node *node)
+{
+ int rc;
+ struct grecs_value *val;
+ struct grecs_txtacc *acc;
+
+ if (node->type != grecs_node_block)
+ return -1;
+
+ if (substatement_find (node, "type", GRECS_TYPE_STRING, 1, &val) !=
+ substatement_success)
+ return -1;
+ acc = grecs_txtacc_create ();
+ rc = xlat_listen_socket_i (node, val->v.string, acc);
+ grecs_txtacc_free (acc);
+ return rc;
+}
+
+
+struct meta1_translator
+{
+ char const *old_name;
+ char const *new_name;
+ int (*translate) (struct grecs_node *);
+};
+
+static struct meta1_translator transtab[] = {
+ { "start_action", "mode", xlat_start_action },
+ { "listen_socket", "socket", xlat_listen_socket },
+ { "pass_fd_socket", "pass-fd-socket" },
+ { "user", "user" },
+ { "path", "program" },
+ { "arguments", "command" },
+ { "restart_dependencies", "dependents", },
+ { NULL }
+};
+
+static struct meta1_translator *
+meta1_translator_lookup (const char *name)
+{
+ struct meta1_translator *p;
+
+ for (p = transtab; p->old_name; p++)
+ if (strcmp (p->old_name, name) == 0)
+ return p;
+ return NULL;
+}
+
+static int
+meta1_translate_stmt (struct grecs_node *stmt, struct component *comp)
+{
+ struct meta1_translator *trans = meta1_translator_lookup (stmt->ident);
+ struct grecs_keyword *kwp;
+
+ if (!trans)
+ return 0;
+ if (trans->translate && trans->translate (stmt))
+ return -1;
+ if (stmt->type != grecs_node_stmt)
+ return -1;
+
+ kwp = find_component_keyword (trans->new_name);
+ grecs_process_ident (kwp, stmt->v.value, comp, &stmt->locus);
+ return 0;
+}
+
+static int
+meta1_translate_node (struct grecs_node *node)
+{
+ struct component *comp;
+ struct grecs_node *stmt;
+ size_t len;
+ int err = 0;
+
+ comp = component_create (node->ident);
+ for (stmt = node->down; stmt; stmt = stmt->next)
+ {
+ if (meta1_translate_stmt (stmt, comp))
+ ++err;
+ }
+ if (err)
+ {
+ component_free (comp);
+ return -1;
+ }
+
+ comp->privs.allgroups = 1;
+ comp->dir = META1_QUEUE_DIR ();
+ comp->redir[RETR_ERR].type = redir_file;
+ comp->redir[RETR_ERR].v.file = NULL;
+ len = 0;
+ grecs_asprintf (&comp->redir[RETR_ERR].v.file, &len,
+ "%s/%s.log", META1_QUEUE_DIR (), comp->tag);
+ component_finish (comp, &node->locus);
+ return 0;
+}
+
+static int
+meta1_translate_node_list (struct grecs_node *node)
+{
+ int err = 0;
+ while (node)
+ {
+ if (meta1_translate_node (node))
+ ++err;
+ node = node->next;
+ }
+ return err;
+}
+
+int
+meta1_config_parse (const char *name)
+{
+ struct grecs_node *subtree;
+ int traceflags = 0;
+ int rc;
+
+ setflag (&traceflags, "META1_DEBUG_YACC", GRECS_TRACE_GRAM);
+ setflag (&traceflags, "META1_DEBUG_LEX", GRECS_TRACE_LEX);
+
+ grecs_error_count = 0;
+ grecs_current_locus_point.file = grecs_install_text (name);
+ grecs_current_locus_point.line = 1;
+ grecs_current_locus_point.col = 0;
+ subtree = grecs_meta1_parser (name, traceflags);
+
+ if (!subtree)
+ return -1;
+
+ rc = meta1_translate_node_list (subtree->down);
+
+ grecs_node_free (subtree);
+
+ return rc;
+}
diff --git a/src/meta1parse.h b/src/meta1parse.h
new file mode 100644
index 0000000..6c64e6c
--- a/dev/null
+++ b/src/meta1parse.h
@@ -0,0 +1,3 @@
+extern char *meta1_queue_dir;
+int meta1_config_parse (const char *name);
+
diff --git a/src/pies.c b/src/pies.c
index 089dd17..4fcb9b3 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -17,7 +17,7 @@
#include "pies.h"
#include <locale.h>
#include <configmake.h>
-#include "meta1lex.h"
+#include "meta1parse.h"
#include "identity.h"
#include "grecsasrt.h"

Return to:

Send suggestions and report system problems to the System administrator.