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(";");
+}