diff src/context.cpp @ 75:1142e46be550

start coding on new config syntax
author carl
date Wed, 13 Jul 2005 23:04:14 -0700
parents b7449114ebb0
children 81f1e400e8ab
line wrap: on
line diff
--- a/src/context.cpp	Sun Jul 10 14:19:00 2005 -0700
+++ b/src/context.cpp	Wed Jul 13 23:04:14 2005 -0700
@@ -28,19 +28,22 @@
 char *token_include;
 char *token_inherit;
 char *token_lbrace;
+char *token_mailhost;
 char *token_many;
 char *token_off;
+char *token_ok2;
 char *token_ok;
-char *token_ok2;
 char *token_on;
 char *token_rbrace;
 char *token_semi;
 char *token_soft;
+char *token_substitute;
 char *token_tld;
 char *token_unknown;
 char *token_white;
 
 string_set all_strings;     // owns all the strings, only modified by the config loader thread
+const int maxlen = 1000;
 
 DNSBL::DNSBL(char *n, char *s, char *m) {
     name    = n;
@@ -74,23 +77,39 @@
 }
 
 
-CONTEXTP CONFIG::find_context(char *to, char *from) {
-    CONTEXTP con = NULL;
-    context_map::iterator i = env_to.find(from);
+void CONFIG::add_to(char *to, CONTEXTP con) {
+    context_map::iterator i = env_to.find(to);
     if (i != env_to.end()) {
-        con = (*i).second;
-        return con->find_from_context(from);
+        CONTEXTP c = (*i).second;
+        if ((c != con) && (c != con->get_parent())) {
+            char oldname[maxlen];
+            char newname[maxlen];
+            char *oldn = c->get_full_name(oldname, maxlen);
+            char *newn = con->get_full_name(newname, maxlen);
+            char buf[maxlen*3];
+            snprintf(buf, maxlen*3, "both %s and %s claim envelope to %s, the second one wins", oldn, newn, to);
+            my_syslog(buf);
     }
+    }
+    env_to[to] = con;
+}
+
+
+CONTEXTP CONFIG::find_context(char *to) {
+    context_map::iterator i = env_to.find(to);
+    if (i != env_to.end()) return (*i).second;      // found user@domain.tld key
     char *x = strchr(to, '@');
     if (x) {
         x++;
         i = env_to.find(x);
-        if (i != env_to.end()) {
-            con = (*i).second;
-            return con->find_from_context(from);
+        if (i != env_to.end()) return (*i).second;  // found domain.tld key
+        char y = *x;
+        *x = '\0';
+        i = env_to.find(to);
+        *x = y;
+        if (i != env_to.end()) return (*i).second;  // found user@ key
         }
-    }
-    return default_context->find_from_context(from);
+    return default_context;
 }
 
 
@@ -101,6 +120,12 @@
         CONTEXTP p = c->get_parent();
         if (!p && (c != default_context)) c->dump();
     }
+    char buf[maxlen];
+    for (context_map::iterator i=env_to.begin(); i!=env_to.end(); i++) {
+        char     *to = (*i).first;
+        CONTEXTP con = (*i).second;
+        printf("// envelope to %s \t-> context %s \n", to, con->get_full_name(buf,maxlen));
+    }
 }
 
 
@@ -111,10 +136,10 @@
     content_filtering   = (parent) ? parent->content_filtering : false;
     content_suffix      = NULL;
     content_message     = NULL;
-    host_limit          = 0;
+    host_limit          = (parent) ? parent->host_limit  : 0;
     host_limit_message  = NULL;
-    host_random         = false;
-    tag_limit           = 0;
+    host_random         = (parent) ? parent->host_random : false;
+    tag_limit           = (parent) ? parent->tag_limit   : 0;
     tag_limit_message   = NULL;
 }
 
@@ -130,7 +155,6 @@
 
 char *CONTEXT::get_full_name(char *buffer, int size) {
     if (!parent) return name;
-    const int maxlen = 1000;
     char buf[maxlen];
     snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name);
     return buffer;
@@ -138,51 +162,51 @@
 
 
 bool CONTEXT::cover_env_to(char *to) {
-    const int maxlen = 1000;
     char buffer[maxlen];
     char *x = strchr(to, '@');
     if (x) x++;
     else   x = to;
+    if (*x == '\0') return true;    // always allow covering addresses with no domain name, eg abuse@
     string_set::iterator i = env_to.find(x);
     if (i != env_to.end()) return true;
-    return (parent) ? parent->cover_env_to(to) : false;
+    return false;
 }
 
 
 char *CONTEXT::find_from(char *from) {
-    // do  we have a white/black/unknown for this full from value?
     string_map::iterator i = env_from.find(from);
-    if (i != env_from.end()) return (*i).second;
-    // do we have a white/black/unknown for the source domain name?
+    if (i != env_from.end()) return (*i).second;        // found user@domain.tld key
     char *x = strchr(from, '@');
     if (x) {
         x++;
         i = env_from.find(x);
-        if (i != env_from.end()) return (*i).second;
+        if (i != env_from.end()) return (*i).second;    // found domain.tld key
+        char y = *x;
+        *x = '\0';
+        i = env_from.find(from);
+        *x = y;
+        if (i != env_from.end()) return (*i).second;      // found user@ key
     }
     if ((env_from_default == token_inherit) && parent) {
         return parent->find_from(from);
     }
-    return env_from_default;
+    return (env_from_default == token_inherit) ? token_unknown : env_from_default;
 }
 
 
-CONTEXTP CONTEXT::find_from_context(char *from) {
-    // do we have a special child context for this full from value?
-    context_map::iterator j = env_from_context.find(from);
-    if (j != env_from_context.end()) {
-        CONTEXTP con = (*j).second;
-        return con->find_from_context(from);
-    }
+CONTEXTP CONTEXT::find_context(char *from) {
+    context_map::iterator i = env_from_context.find(from);
+    if (i != env_from_context.end()) return (*i).second;        // found user@domain.tld key
     char *x = strchr(from, '@');
     if (x) {
         x++;
-        // do we have a special context for the source domain name?
-        j = env_from_context.find(x);
-        if (j != env_from_context.end()) {
-            CONTEXTP con = (*j).second;
-            return con->find_from_context(from);
-        }
+        i = env_from_context.find(x);
+        if (i != env_from_context.end()) return (*i).second;    // found domain.tld key
+        char y = *x;
+        *x = '\0';
+        i = env_from_context.find(from);
+        *x = y;
+        if (i != env_from_context.end()) return (*i).second;              // found user@ key
     }
     return this;
 }
@@ -216,12 +240,13 @@
 
 
 void CONTEXT::dump(int level) {
-    const int maxlen = 1000;
     char indent[maxlen];
     int i = min(maxlen-1, level*4);
     memset(indent, ' ', i);
     indent[i] = '\0';
-    printf("%s context %s { \n", indent, name);
+    char buf[maxlen];
+    char *fullname = get_full_name(buf,maxlen);
+    printf("%s context %s { \t// %s\n", indent, name, fullname);
 
     for (dnsblp_map::iterator i=dnsbl_names.begin(); i!=dnsbl_names.end(); i++) {
         char *n = (*i).first;
@@ -276,10 +301,10 @@
             printf("%s         host_limit off; \n", indent);
         }
         if (tag_limit_message) {
-            printf("%s         tag_limit on %d \"%s\"; \n", indent, tag_limit, tag_limit_message);
+            printf("%s         html_limit on %d \"%s\"; \n", indent, tag_limit, tag_limit_message);
         }
         else {
-            printf("%s         tag_limit off; \n", indent);
+            printf("%s         html_limit off; \n", indent);
         }
         printf("%s     }; \n", indent);
         }
@@ -287,7 +312,7 @@
         printf("%s     content off {}; \n", indent, env_from_default);
     }
 
-    printf("%s     env_to { \n", indent);
+    printf("%s     env_to { \t// %s\n", indent, fullname);
     for (string_set::iterator i=env_to.begin(); i!=env_to.end(); i++) {
         printf("%s         %s; \n", indent, *i);
     }
@@ -298,7 +323,7 @@
         c->dump(level+1);
     }
 
-    printf("%s     env_from %s { \n", indent, env_from_default);
+    printf("%s     env_from %s { \t// %s\n", indent, env_from_default, fullname);
     if (!env_from.empty()) {
         printf("%s     // white/black/unknown \n", indent);
         for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) {
@@ -402,6 +427,7 @@
 //
 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
+    bool topdefault = (!me.get_parent()) && (!dc.default_context);
     char *setting = tok.next();
     if (setting == token_on) {
         me.set_content_filtering(true);
@@ -418,9 +444,14 @@
         char *have = tok.next();
         if (!have) break;
         if (have == token_filter) {
-            me.set_content_suffix(tok.next());
-            me.set_content_message(tok.next());
+            char *suffix = tok.next();
+            char *messag = tok.next();
+            if (topdefault) {
+                me.set_content_suffix(suffix);
+                me.set_content_message(messag);
+            }
             if (!tsa(tok, token_semi)) return false;
+            if (!topdefault) tok.token_error("content filters may only be speciried in the top default context");
         }
         else if (have == token_ignore) {
             if (!tsa(tok, token_lbrace)) return false;
@@ -445,10 +476,11 @@
                     break;  // done
                 }
                 else {
-                    me.add_tld(have);
+                    if (topdefault) me.add_tld(have);
                 }
             }
             if (!tsa(tok, token_semi)) return false;
+            if (!topdefault) tok.token_error("tld values may only be specified in the top default context");
         }
         else if (have == token_html_limit) {
             have = tok.next();
@@ -475,10 +507,11 @@
                     break;  // done
                 }
                 else {
-                    me.add_tag(have);
+                    if (topdefault) me.add_tag(have);
                 }
             }
             if (!tsa(tok, token_semi)) return false;
+            if (!topdefault) tok.token_error("html tags may only be specified in the top default context");
         }
         else if (have == token_host_limit) {
             have = tok.next();
@@ -552,6 +585,17 @@
                         }
                     }
                 }
+                else if (have == token_substitute) {
+                    if (tok.next() == token_mailhost) {
+                        have = tok.next();
+                        if (keeping) {
+                            if (me.allow_env_to(have)) {
+                                me.add_to(have);
+                                dc.add_to(have, &me);
+                            }
+                        }
+                    }
+                }
                 tok.skipeol();
             }
         }
@@ -560,7 +604,7 @@
             dc.add_to(have, &me);
         }
         else {
-            tok.token_error("valid env_to address or domain name", have);
+            tok.token_error("user@ or user@domain.tld or domain.tld where domain.tld allowed by parent context", have);
             return false;
         }
     }
@@ -573,7 +617,7 @@
 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
     char *st = tok.next();
-    if ((st == token_black) || (st == token_white) || (st == token_unknown)) {
+    if ((st == token_black) || (st == token_white) || (st == token_unknown) || (st == token_inherit)) {
         me.set_from_default(st);
     }
     else {
@@ -615,6 +659,12 @@
                         me.add_from(have, (many) ? token_black : token_white);
                     }
                 }
+                else if (have == token_substitute) {
+                    if (tok.next() == token_mailhost) {
+                        have = tok.next();
+                        me.add_from(have, (many) ? token_black : token_white);
+                    }
+                }
                 tok.skipeol();
             }
         }
@@ -730,6 +780,7 @@
     token_include    = register_string("include");
     token_inherit    = register_string("inherit");
     token_lbrace     = register_string("{");
+    token_mailhost   = register_string("mail_host");
     token_many       = register_string("many");
     token_off        = register_string("off");
     token_ok         = register_string("ok");
@@ -738,6 +789,7 @@
     token_rbrace     = register_string("}");
     token_semi       = register_string(";");
     token_soft       = register_string("soft");
+    token_substitute = register_string("substitute");
     token_tld        = register_string("tld");
     token_unknown    = register_string("unknown");
     token_white      = register_string("white");