X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=postlicyd%2Fconfig.c;h=672faca0844a3e730bd01a25b2b053560847bee8;hb=59b8220d0227fe68537a563b3e5fa2e63e26bc0d;hp=7ea485c379636301d9c25aaacf20849e3a7145d9;hpb=2520de08ed80b941f28c9ccb97a3785a507a831d;p=apps%2Fpfixtools.git diff --git a/postlicyd/config.c b/postlicyd/config.c index 7ea485c..672faca 100644 --- a/postlicyd/config.c +++ b/postlicyd/config.c @@ -72,9 +72,18 @@ config_param_register("ehlo_filter"); */ config_param_register("verify_filter"); + +/* Where to bind the server. + */ +config_param_register("port"); + + +static config_t *global_config = NULL; + static inline config_t *config_new(void) { config_t *config = p_new(config_t, 1); + global_config = config; return config; } @@ -92,9 +101,17 @@ void config_delete(config_t **config) if (*config) { config_close(*config); p_delete(config); + global_config = NULL; } } +static void config_exit() +{ + if (global_config) { + config_delete(&global_config); + } +} +module_exit(config_exit); static bool config_second_pass(config_t *config) { @@ -121,6 +138,11 @@ static bool config_second_pass(config_t *config) } ok = false; +#define PARSE_CHECK(Expr, Fmt, ...) \ + if (!(Expr)) { \ + err(Fmt, ##__VA_ARGS__); \ + return false; \ + } foreach (filter_param_t *param, config->params) { switch (param->type) { #define CASE(Param, State) \ @@ -128,6 +150,8 @@ static bool config_second_pass(config_t *config) ok = true; \ config->entry_points[SMTP_ ## State] \ = filter_find_with_name(&config->filters, param->value); \ + PARSE_CHECK(config->entry_points[SMTP_ ## State] >= 0, \ + "invalid filter name %s", param->value); \ break; CASE(CLIENT, CONNECT) CASE(EHLO, EHLO) @@ -139,13 +163,14 @@ static bool config_second_pass(config_t *config) CASE(VERIFY, VRFY) CASE(ETRN, ETRN) #undef CASE + FILTER_PARAM_PARSE_INT(PORT, config->port); default: break; } }} array_deep_wipe(config->params, filter_params_wipe); if (!ok) { - syslog(LOG_ERR, "no entry point defined"); + err("no entry point defined"); } return ok; @@ -158,10 +183,12 @@ static bool config_load(config_t *config) const char *p; int line = 0; const char *linep; + bool in_section = false; + bool end_of_section = false; char key[BUFSIZ]; char value[BUFSIZ]; - ssize_t key_len, value_len; + int key_len, value_len; if (!file_map_open(&map, config->filename, false)) { return false; @@ -171,10 +198,12 @@ static bool config_load(config_t *config) filter_init(&filter); linep = p = map.map; +#define READ_LOG(Lev, Fmt, ...) \ + __log(LOG_ ## Lev, "config file %s:%d:%d: " Fmt, config->filename, \ + line + 1, (int)(p - linep + 1), ##__VA_ARGS__) #define READ_ERROR(Fmt, ...) \ do { \ - syslog(LOG_ERR, "config file %s:%d:%d: " Fmt, config->filename, \ - line + 1, p - linep + 1, ##__VA_ARGS__); \ + READ_LOG(ERR, Fmt, ##__VA_ARGS__); \ goto error; \ } while (0) #define ADD_IN_BUFFER(Buffer, Len, Char) \ @@ -185,17 +214,23 @@ static bool config_load(config_t *config) (Buffer)[(Len)++] = (Char); \ (Buffer)[(Len)] = '\0'; \ } while (0) -#define READ_NEXT(OnEOF) \ +#define READ_NEXT \ do { \ if (*p == '\n') { \ ++line; \ linep = p + 1; \ } \ if (++p >= map.end) { \ - OnEOF; \ + if (!end_of_section) { \ + if (in_section) { \ + goto badeof; \ + } else { \ + goto ok; \ + } \ + } \ } \ } while (0) -#define READ_BLANK(OnEOF) \ +#define READ_BLANK \ do { \ bool in_comment = false; \ while (in_comment || isspace(*p) || *p == '#') { \ @@ -204,7 +239,7 @@ static bool config_load(config_t *config) } else if (*p == '#') { \ in_comment = true; \ } \ - READ_NEXT(OnEOF); \ + READ_NEXT; \ } \ } while (0) #define READ_TOKEN(Name, Buffer, Len) \ @@ -216,17 +251,17 @@ static bool config_load(config_t *config) } \ do { \ ADD_IN_BUFFER(Buffer, Len, *p); \ - READ_NEXT(goto badeof); \ + READ_NEXT; \ } while (isalnum(*p) || *p == '_'); \ } while (0) -#define READ_STRING(Name, Buffer, Len, OnEOF) \ +#define READ_STRING(Name, Buffer, Len, Ignore) \ do { \ (Len) = 0; \ (Buffer)[0] = '\0'; \ if (*p == '"') { \ bool escaped = false; \ while (*p == '"') { \ - READ_NEXT(goto badeof); \ + READ_NEXT; \ while (true) { \ if (*p == '\n') { \ READ_ERROR("string must not contain EOL"); \ @@ -236,14 +271,14 @@ static bool config_load(config_t *config) } else if (*p == '\\') { \ escaped = true; \ } else if (*p == '"') { \ - READ_NEXT(goto badeof); \ + READ_NEXT; \ break; \ } else { \ ADD_IN_BUFFER(Buffer, Len, *p); \ } \ - READ_NEXT(goto badeof); \ + READ_NEXT; \ } \ - READ_BLANK(goto badeof); \ + READ_BLANK; \ } \ if (*p != ';') { \ READ_ERROR("%s must end with a ';'", Name); \ @@ -253,7 +288,7 @@ static bool config_load(config_t *config) while (*p != ';' && isascii(*p) && (isprint(*p) || isspace(*p))) { \ if (escaped) { \ if (*p == '\r' || *p == '\n') { \ - READ_BLANK(goto badeof); \ + READ_BLANK; \ } else { \ ADD_IN_BUFFER(Buffer, Len, '\\'); \ } \ @@ -266,7 +301,7 @@ static bool config_load(config_t *config) } else { \ ADD_IN_BUFFER(Buffer, Len, *p); \ } \ - READ_NEXT(goto badeof); \ + READ_NEXT; \ } \ if (escaped) { \ ADD_IN_BUFFER(Buffer, Len, '\\'); \ @@ -275,7 +310,8 @@ static bool config_load(config_t *config) (Buffer)[--(Len)] = '\0'; \ } \ } \ - READ_NEXT(OnEOF); \ + end_of_section = Ignore; \ + READ_NEXT; \ } while(0) @@ -287,23 +323,25 @@ read_section: value[0] = key[0] = '\0'; value_len = key_len = 0; - READ_BLANK(goto ok); + in_section = end_of_section = false; + READ_BLANK; + in_section = true; READ_TOKEN("section name", key, key_len); - READ_BLANK(goto badeof); + READ_BLANK; switch (*p) { case '=': - READ_NEXT(goto badeof); + READ_NEXT; goto read_param_value; case '{': - READ_NEXT(goto badeof); + READ_NEXT; goto read_filter; default: READ_ERROR("invalid character '%c', expected '=' or '{'", *p); } read_param_value: - READ_BLANK(goto badeof); - READ_STRING("parameter value", value, value_len, ;); + READ_BLANK; + READ_STRING("parameter value", value, value_len, true); { filter_param_t param; param.type = param_tokenize(key, key_len); @@ -311,23 +349,25 @@ read_param_value: param.value = p_dupstr(value, value_len); param.value_len = value_len; array_add(config->params, param); + } else { + READ_LOG(INFO, "unknown parameter %.*s", key_len, key); } } goto read_section; read_filter: filter_set_name(&filter, key, key_len); - READ_BLANK(goto badeof); + READ_BLANK; while (*p != '}') { READ_TOKEN("filter parameter name", key, key_len); - READ_BLANK(goto badeof); + READ_BLANK; if (*p != '=') { READ_ERROR("invalid character '%c', expected '='", *p); } - READ_NEXT(goto badeof); - READ_BLANK(goto badeof); - READ_STRING("filter parameter value", value, value_len, goto badeof); - READ_BLANK(goto badeof); + READ_NEXT; + READ_BLANK; + READ_STRING("filter parameter value", value, value_len, false); + READ_BLANK; if (strcmp(key, "type") == 0) { if (!filter_set_type(&filter, value, value_len)) { READ_ERROR("unknow filter type (%s) for filter %s", @@ -346,7 +386,8 @@ read_filter: (void)filter_add_param(&filter, key, key_len, value, value_len); } } - READ_NEXT(;); + end_of_section = true; + READ_NEXT; if (!filter_build(&filter)) { READ_ERROR("invalid filter %s", filter.name); } @@ -362,7 +403,7 @@ ok: return true; badeof: - syslog(LOG_ERR, "Unexpected end of file"); + err("Unexpected end of file"); error: if (filter.name) { @@ -382,7 +423,7 @@ config_t *config_read(const char *file) config_t *config = config_new(); config->filename = file; if (!config_reload(config)) { - p_delete(&config); + config_delete(&config); return NULL; } return config;