Mercurial > sm-archive
view src/context.cpp @ 5:b8a3b366635a
initial version
author | carl |
---|---|
date | Fri, 10 Mar 2006 12:06:40 -0800 |
parents | 01268466f0dc |
children | 61a4e8773e2e |
line wrap: on
line source
/* 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_include; 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("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_semi = register_string(";"); }