diff --git a/include/common/cfgparse.h b/include/common/cfgparse.h index bba18cfe1b..c5777f98b6 100644 --- a/include/common/cfgparse.h +++ b/include/common/cfgparse.h @@ -2,7 +2,7 @@ include/common/cfgparse.h Configuration parsing functions. - Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu + Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -22,20 +22,47 @@ #ifndef _COMMON_CFGPARSE_H #define _COMMON_CFGPARSE_H +#include #include +#include + +#include /* configuration sections */ #define CFG_NONE 0 #define CFG_GLOBAL 1 #define CFG_LISTEN 2 +struct cfg_keyword { + int section; /* section type for this keyword */ + const char *kw; /* the keyword itself */ + int (*parse)(char **args, /* command line and arguments */ + int section_type, /* current section CFG_{GLOBAL|LISTEN} */ + struct proxy *curpx, /* current proxy (NULL in GLOBAL) */ + struct proxy *defpx, /* default proxy (NULL in GLOBAL) */ + char *err, /* error message buffer (do not add '\n') */ + int errlen); /* error buffer size, '\0' included */ +}; + +/* A keyword list. It is a NULL-terminated array of keywords. It embeds a + * struct list in order to be linked to other lists, allowing it to easily + * be declared where it is needed, and linked without duplicating data nor + * allocating memory. + */ +struct cfg_kw_list { + struct list list; + struct cfg_keyword kw[VAR_ARRAY]; +}; + + extern int cfg_maxpconn; extern int cfg_maxconn; int cfg_parse_global(const char *file, int linenum, char **args, int inv); int cfg_parse_listen(const char *file, int linenum, char **args, int inv); int readcfgfile(const char *file); - +void cfg_register_keywords(struct cfg_kw_list *kwl); +void cfg_unregister_keywords(struct cfg_kw_list *kwl); #endif /* _COMMON_CFGPARSE_H */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 8afc69c9c7..b202923ed8 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -121,6 +121,11 @@ static struct proxy defproxy; /* fake proxy used to assign default values on al int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */ int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */ +/* List head of all known configuration keywords */ +static struct cfg_kw_list cfg_keywords = { + .list = LIST_HEAD_INIT(cfg_keywords.list) +}; + /* * converts to a list of listeners which are dynamically allocated. * The format is "{addr|'*'}:port[-end][,{addr|'*'}:port[-end]]*", where : @@ -501,6 +506,26 @@ int cfg_parse_global(const char *file, int linenum, char **args, int inv) } } else { + struct cfg_kw_list *kwl; + int index; + + list_for_each_entry(kwl, &cfg_keywords.list, list) { + for (index = 0; kwl->kw[index].kw != NULL; index++) { + if (kwl->kw[index].section != CFG_GLOBAL) + continue; + if (strcmp(kwl->kw[index].kw, args[0]) == 0) { + /* prepare error message just in case */ + snprintf(trash, sizeof(trash), + "error near '%s' in '%s' section", args[0], "global"); + if (kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, trash, sizeof(trash)) < 0) { + Alert("parsing [%s:%d] : %s\n", file, linenum, trash); + return -1; + } + return 0; + } + } + } + Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], "global"); return -1; } @@ -2651,6 +2676,26 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) } } else { + struct cfg_kw_list *kwl; + int index; + + list_for_each_entry(kwl, &cfg_keywords.list, list) { + for (index = 0; kwl->kw[index].kw != NULL; index++) { + if (kwl->kw[index].section != CFG_LISTEN) + continue; + if (strcmp(kwl->kw[index].kw, args[0]) == 0) { + /* prepare error message just in case */ + snprintf(trash, sizeof(trash), + "error near '%s' in %s section", args[0], cursection); + if (kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, trash, sizeof(trash)) < 0) { + Alert("parsing [%s:%d] : %s\n", file, linenum, trash); + return -1; + } + return 0; + } + } + } + Alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section\n", file, linenum, args[0], cursection); return -1; } @@ -3232,7 +3277,23 @@ int readcfgfile(const char *file) return -1; } +/* + * Registers the CFG keyword list as a list of valid keywords for next + * parsing sessions. + */ +void cfg_register_keywords(struct cfg_kw_list *kwl) +{ + LIST_ADDQ(&cfg_keywords.list, &kwl->list); +} +/* + * Unregisters the CFG keyword list from the list of valid keywords. + */ +void cfg_unregister_keywords(struct cfg_kw_list *kwl) +{ + LIST_DEL(&kwl->list); + LIST_INIT(&kwl->list); +} /* * Local variables: