Mercurial > sm-archive
diff src/context.cpp @ 0:616666e2f34c
initial version
author | carl |
---|---|
date | Fri, 10 Mar 2006 10:30:08 -0800 |
parents | |
children | 01268466f0dc |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/context.cpp Fri Mar 10 10:30:08 2006 -0800 @@ -0,0 +1,202 @@ +/* + +Copyright (c) 2004 Carl Byington - 510 Software Group, released under +the GPL version 2 or any later version at your choice available at +http://www.fsf.org/licenses/gpl.txt + +*/ + +#include "includes.h" + +// needed for socket io +#include <unistd.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/un.h> + +static char* context_version="$Id$"; + +char *token_envfrom; +char *token_lbrace; +char *token_rbrace; +char *token_rcptto; +char *token_semi; + +string_set all_strings; // owns all the strings, only modified by the config loader thread +const int maxlen = 1000; // used for snprintf buffers + +CONFIG::CONFIG() { + reference_count = 0; + generation = 0; + load_time = 0; +} + + +CONFIG::~CONFIG() { +} + + +char *CONFIG::find(char *needle, &string_map haystack) { + string_map::iterator i = haystack.find(needle); + if (i != haystack.end()) return (*i).second; // found user@domain.tld key + char *x = strchr(needle, '@'); + if (x) { + x++; + i = haystack.find(x); + if (i != haystack.end()) return (*i).second; // found domain.tld key + char y = *x; + *x = '\0'; + i = haystack.find(needle); + *x = y; + if (i != haystack.end()) return (*i).second; // found user@ key + } + return NULL; +} + + +void CONFIG::dump() { + printf("rcpt_to {\n"); + for (string_map::iterator i=rcpt_to.begin(); i!=rcpt_to.end(); i++) { + char *to = (*i).first; + char *target = (*i).second; + printf(" %s \t %s\n", to, target); + } + printf("};\n"); + printf("env_from {\n"); + for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) { + char *from = (*i).first; + char *target = (*i).second; + printf(" %s \t %s\n", from, target); + } + printf("};\n"); +} + + +//////////////////////////////////////////////// +// helper to discard the strings held by a string_set +// +void discard(string_set &s) { + for (string_set::iterator i=s.begin(); i!=s.end(); i++) { + free(*i); + } + s.clear(); +} + + +//////////////////////////////////////////////// +// helper to register a string in a string set +// +char* register_string(string_set &s, char *name) { + string_set::iterator i = s.find(name); + if (i != s.end()) return *i; + char *x = strdup(name); + s.insert(x); + return x; +} + + +//////////////////////////////////////////////// +// register a global string +// +char* register_string(char *name) { + return register_string(all_strings, name); +} + + +//////////////////////////////////////////////// +// +bool tsa(TOKEN &tok, char *token); +bool tsa(TOKEN &tok, char *token) { + char *have = tok.next(); + if (have == token) return true; + tok.token_error(token, have); + return false; +} + + +//////////////////////////////////////////////// +// +bool parse_rcpt_to(TOKEN &tok, CONFIG &dc); +bool parse_rcpt_to(TOKEN &tok, CONFIG &dc) { + if (!tsa(tok, token_lbrace)) return false; + while (true) { + char *have = tok.next(); + if (!have) break; + if (have == token_rbrace) break; + if (have == token_semi) { + // optional separators + } + else { + char *target = tok.next(); + dc.add_to(have, target); + } + } + return tsa(tok, token_semi); +} + + +//////////////////////////////////////////////// +// +bool parse_env_from(TOKEN &tok, CONFIG &dc); +bool parse_env_from(TOKEN &tok, CONFIG &dc) { + if (!tsa(tok, token_lbrace)) return false; + while (true) { + char *have = tok.next(); + if (!have) break; + if (have == token_rbrace) break; + if (have == token_semi) { + // optional separators + } + else { + char *target = tok.next(); + dc.add_from(have, target); + } + } + return tsa(tok, token_semi); +} + + +//////////////////////////////////////////////// +// parse a config file +// +bool load_conf(CONFIG &dc, char *fn) { + TOKEN tok(fn, &dc.config_files); + while (true) { + char *have = tok.next(); + if (!have) break; + if (have == token_envfrom) { + if (!parse_env_from(tok, dc)) { + tok.token_error("load_conf() failed to parse env_from"); + return false; + } + } + else if (have == token_rcptto) { + if (!parse_rcpt_to(tok, dc)) { + tok.token_error("load_conf() failed to parse rcpt_to"); + return false; + } + } + else { + tok.token_error(token_context, have); + return false; + } + } + return true; +} + + +//////////////////////////////////////////////// +// init the tokens +// +void token_init() { + token_envfrom = register_string("env_from"); + token_lbrace = register_string("{"); + token_rbrace = register_string("}"); + token_rcptto = register_string("rcpt_to"); + token_semi = register_string(";"); +}