X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/a8b9c5eb837178fbf0ce7b4db2d3e067c1151b65..a9bd543ab4ebe415bca9d6f27b90f16ddac79bc0:/conf.c diff --git a/conf.c b/conf.c index 9baa6de..a31d179 100644 --- a/conf.c +++ b/conf.c @@ -1,13 +1,11 @@ /* -*-c-*- * - * $Id: conf.c,v 1.8 2001/02/03 20:33:26 mdw Exp $ - * * Configuration parsing * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of the `fw' port forwarder. * @@ -15,86 +13,25 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * `fw' 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 `fw'; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: conf.c,v $ - * Revision 1.8 2001/02/03 20:33:26 mdw - * Fix flags to be unsigned. - * - * Revision 1.7 2000/08/01 17:58:10 mdw - * Fix subtleties with functions. - * - * Revision 1.6 2000/02/12 18:13:20 mdw - * Terminate tables of sources and targets. - * - * Revision 1.5 1999/10/22 22:46:44 mdw - * Improve documentation for conf_enum. - * - * Revision 1.4 1999/10/15 21:12:36 mdw - * Remove redundant debugging code. - * - * Revision 1.3 1999/08/19 18:32:48 mdw - * Improve lexical analysis. In particular, `chmod' patterns don't have to - * be quoted any more. - * - * Revision 1.2 1999/07/26 23:28:39 mdw - * Major reconstruction work for new design. - * - * Revision 1.1.1.1 1999/07/01 08:56:23 mdw - * Initial revision. - * - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#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 }; - -static const char *notword = 0; -static const char *notdelim = 0; +#include "fw.h" /*----- Main code ---------------------------------------------------------*/ -/* --- @undelim@ --- * +/* --- @conf_undelim@ --- * * - * Arguments: @const char *d, dd@ = pointer to characters to escape + * Arguments: @scanner *sc@ = pointer to scanner definition + * @const char *d, *dd@ = pointer to characters to escape * * Returns: --- * @@ -103,7 +40,11 @@ static const char *notdelim = 0; * second list will always be allowed to continue a word. */ -void undelim(const char *d, const char *dd) { notword = d; notdelim = dd; } +void conf_undelim(scanner *sc, const char *d, const char *dd) +{ + sc->wbegin = d; + sc->wcont = dd; +} /* --- @token@ --- * * @@ -134,7 +75,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; @@ -159,7 +100,7 @@ int token(scanner *sc) /* --- Various self-delimiting characters --- */ case SELFDELIM: - if (!notword || strchr(notword, ch) == 0) { + if (!sc->wbegin || strchr(sc->wbegin, ch) == 0) { dstr_putc(&sc->d, ch); dstr_putz(&sc->d); sc->t = ch; @@ -189,7 +130,7 @@ int token(scanner *sc) q = !q; break; case SELFDELIM: - if (q || (notdelim && strchr(notdelim, ch))) + if (q || (sc->wcont && strchr(sc->wcont, ch))) goto insert; goto word; default: @@ -224,7 +165,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; @@ -391,7 +332,7 @@ void conf_name(scanner *sc, char delim, dstr *d) if (sc->t == '[') { token(sc); - f |= f_bra; + f |= f_bra | f_ok; } /* --- Do the main reading sequence --- */ @@ -428,169 +369,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 -------------------------------------------------*/