Mercurial > sm-archive
view src/context.cpp @ 18:e1a028daceb9
Added tag stable-1-6 for changeset 8ebecad6530f
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 21 Mar 2008 16:02:40 -0700 |
parents | 8ebecad6530f |
children | b24369330483 |
line wrap: on
line source
/* Copyright (c) 2007 Carl Byington - 510 Software Group, released under the GPL version 3 or any later version at your choice available at http://www.gnu.org/licenses/gpl-3.0.txt */ #include "includes.h" char *token_envfrom; char *token_include; char *token_lbrace; char *token_rbrace; char *token_rcptto; char *token_remove; 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() { } bool CONFIG::find(char *needle, string_set &haystack) { string_set::iterator i = haystack.find(needle); if (i != haystack.end()) return true; // found user@domain.tld key char *x = strchr(needle, '@'); if (x) { x++; i = haystack.find(x); if (i != haystack.end()) return true; // found domain.tld key char y = *x; *x = '\0'; i = haystack.find(needle); *x = y; if (i != haystack.end()) return true; // found user@ key } return false; } 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; if (!target) target = "\"\""; bool rem = find_remove(to); printf(" %s \t %s%s;\n", to, target, (rem) ? " remove" : ""); } 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; if (!target) target = "\"\""; 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); } //////////////////////////////////////////////// // clear all global strings, helper for valgrind checking // void clear_strings() { discard(all_strings); } //////////////////////////////////////////////// // 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; char *target = tok.next(); dc.add_to(have, target); target = tok.next(); if (target == token_remove) { dc.add_remove(have); target = tok.next(); } if (target != token_semi) { tok.token_error(token_semi, target); break; } } 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("env_from/rcpt_to", have); return false; } } return true; } //////////////////////////////////////////////// // init the tokens // void token_init() { token_envfrom = register_string("env_from"); token_include = register_string("include"); token_lbrace = register_string("{"); token_rbrace = register_string("}"); token_rcptto = register_string("rcpt_to"); token_remove = register_string("remove"); token_semi = register_string(";"); }