X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/2234f01d91a8582111d3484e60fe1372f11df2db..00e3c0f1bbe99682debd4e34d3d3bd950f8c30cb:/conf.c diff --git a/conf.c b/conf.c index 0cd4a17..57947ca 100644 --- a/conf.c +++ b/conf.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: conf.c,v 1.9 2002/01/13 14:48:16 mdw Exp $ + * $Id: conf.c,v 1.10 2002/02/22 23:42:56 mdw Exp $ * * Configuration parsing * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: conf.c,v $ + * Revision 1.10 2002/02/22 23:42:56 mdw + * `fw'-specific configuration code moved out. This file might become part + * of a library some day. + * * Revision 1.9 2002/01/13 14:48:16 mdw * Make delimiters be a property of a scanner. Change the delimiter- * changing functions' names. @@ -62,8 +66,6 @@ /*----- Header files ------------------------------------------------------*/ -#include "config.h" - #include #include #include @@ -77,19 +79,6 @@ #include "conf.h" #include "scan.h" -#include "source.h" -#include "target.h" - -#include "exec.h" -#include "file.h" -#include "socket.h" - -/*----- Source and target tables ------------------------------------------*/ - -static source_ops *sources[] = - { &xsource_ops, &fsource_ops, &ssource_ops, 0 }; -static target_ops *targets[] = - { &xtarget_ops, &ftarget_ops, &starget_ops, 0 }; /*----- Main code ---------------------------------------------------------*/ @@ -140,7 +129,7 @@ int token(scanner *sc) if (sc->head->tok) { dstr_puts(&sc->d, sc->head->tok); - free(sc->head->tok); + xfree(sc->head->tok); sc->head->tok = 0; sc->t = sc->head->t; goto done; @@ -230,7 +219,7 @@ done: * to pushing a new scanner source. */ -static void pushback(scanner *sc) +void pushback(scanner *sc) { sc->head->tok = xstrdup(sc->d.buf); sc->head->t = sc->t; @@ -434,169 +423,4 @@ void conf_name(scanner *sc, char delim, dstr *d) #undef f_bra } -/* --- @conf_parse@ --- * - * - * Arguments: @scanner *sc@ = pointer to scanner definition - * - * Returns: --- - * - * Use: Parses a configuration file from the scanner. - */ - -void conf_parse(scanner *sc) -{ - token(sc); - - for (;;) { - if (sc->t == CTOK_EOF) - break; - if (sc->t != CTOK_WORD) - error(sc, "parse error, keyword expected"); - - /* --- Handle a forwarding request --- */ - - if (strcmp(sc->d.buf, "forward") == 0 || - strcmp(sc->d.buf, "fw") == 0 || - strcmp(sc->d.buf, "from") == 0) { - source *s; - target *t; - - token(sc); - - /* --- Read a source description --- */ - - { - source_ops **sops; - - /* --- Try to find a source type which understands --- */ - - s = 0; - for (sops = sources; *sops; sops++) { - if ((s = (*sops)->read(sc)) != 0) - goto found_source; - } - error(sc, "unknown source name `%s'", sc->d.buf); - - /* --- Read any source-specific options --- */ - - found_source: - if (sc->t == '{') { - token(sc); - while (sc->t == CTOK_WORD) { - if (!s->ops->option || !s->ops->option(s, sc)) { - error(sc, "unknown %s source option `%s'", - s->ops->name, sc->d.buf); - } - if (sc->t == ';') - token(sc); - } - if (sc->t != '}') - error(sc, "parse error, missing `}'"); - token(sc); - } - } - - /* --- Read a destination description --- */ - - if (sc->t == CTOK_WORD && (strcmp(sc->d.buf, "to") == 0 || - strcmp(sc->d.buf, "->") == 0)) - token(sc); - - { - target_ops **tops; - - /* --- Try to find a target which understands --- */ - - t = 0; - for (tops = targets; *tops; tops++) { - if ((t = (*tops)->read(sc)) != 0) - goto found_target; - } - error(sc, "unknown target name `%s'", sc->d.buf); - - /* --- Read any target-specific options --- */ - - found_target: - if (sc->t == '{') { - token(sc); - while (sc->t == CTOK_WORD) { - if (!t->ops->option || !t->ops->option(t, sc)) { - error(sc, "unknown %s target option `%s'", - t->ops->name, sc->d.buf); - } - if (sc->t == ';') - token(sc); - } - if (sc->t != '}') - error(sc, "parse error, `}' expected"); - token(sc); - } - } - - /* --- Combine the source and target --- */ - - s->ops->attach(s, sc, t); - } - - /* --- Include configuration from a file --- * - * - * Slightly tricky. Scan the optional semicolon from the including - * stream, not the included one. - */ - - else if (strcmp(sc->d.buf, "include") == 0) { - FILE *fp; - dstr d = DSTR_INIT; - - token(sc); - conf_name(sc, '/', &d); - if ((fp = fopen(d.buf, "r")) == 0) - error(sc, "can't include `%s': %s", d.buf, strerror(errno)); - if (sc->t == ';') - token(sc); - pushback(sc); - scan_push(sc, scan_file(fp, xstrdup(d.buf), SCF_FREENAME)); - token(sc); - dstr_destroy(&d); - continue; /* Don't parse a trailing `;' */ - } - - /* --- Other configuration is handled elsewhere --- */ - - else { - - /* --- First try among the sources --- */ - - { - source_ops **sops; - - for (sops = sources; *sops; sops++) { - if ((*sops)->option && (*sops)->option(0, sc)) - goto found_option; - } - } - - /* --- Then try among the targets --- */ - - { - target_ops **tops; - - for (tops = targets; *tops; tops++) { - if ((*tops)->option && (*tops)->option(0, sc)) - goto found_option; - } - } - - /* --- Nobody wants the option --- */ - - error(sc, "unknown global option or prefix `%s'", sc->d.buf); - - found_option:; - } - - if (sc->t == ';') - token(sc); - } -} - /*----- That's all, folks -------------------------------------------------*/