changeset 214:82886d4dd71f stable-6-0-19

Fixes to compile on Fedora 9 and for const correctness.
author Carl Byington <carl@five-ten-sg.com>
date Tue, 10 Jun 2008 08:58:42 -0700
parents 44ffef730bc4
children faac35ae3ccc
files ChangeLog NEWS configure.in dnsbl.spec.in src/context.cpp src/context.h src/dccifd.cpp src/dccifd.h src/dnsbl.cpp src/dnsbl.h src/includes.h src/scanner.h src/spamass.cpp.in src/spamass.h src/tokenizer.cpp src/tokenizer.h xml/dnsbl.in
diffstat 17 files changed, 1120 insertions(+), 1129 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Apr 30 13:11:32 2008 -0700
+++ b/ChangeLog	Tue Jun 10 08:58:42 2008 -0700
@@ -1,3 +1,6 @@
+6.19 2008-06-10
+    Fixes to compile on Fedora 9 and for const correctness.
+
 6.18 2008-03-22
     Extend auto-whitelisting when receiving mail even if the auto
     whitelist is specified in a parent context. Fixes for Solaris from sm-archive.
--- a/NEWS	Wed Apr 30 13:11:32 2008 -0700
+++ b/NEWS	Tue Jun 10 08:58:42 2008 -0700
@@ -1,3 +1,4 @@
+6.19 2008-06-10 Fixes to compile on Fedora 9 and for const correctness.
 6.18 2008-03-22 Extend auto-whitelisting even if specified in a parent context.
 6.17 2008-03-04 Verify all from/to pairs, fix dcc bulk thresholds of many.
 6.16 2008-02-02 Switch to Mercurial source control.
--- a/configure.in	Wed Apr 30 13:11:32 2008 -0700
+++ b/configure.in	Tue Jun 10 08:58:42 2008 -0700
@@ -1,6 +1,6 @@
 
 AC_PREREQ(2.59)
-AC_INIT(dnsbl,6.18,carl@five-ten-sg.com)
+AC_INIT(dnsbl,6.19,carl@five-ten-sg.com)
 AC_CONFIG_SRCDIR([config.h.in])
 AC_CONFIG_HEADER([config.h])
 
--- a/dnsbl.spec.in	Wed Apr 30 13:11:32 2008 -0700
+++ b/dnsbl.spec.in	Tue Jun 10 08:58:42 2008 -0700
@@ -9,7 +9,6 @@
 Source:             http://www.five-ten-sg.com/%{name}/packages/%{name}-%{version}.tar.gz
 BuildRoot:          %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 URL:                http://www.five-ten-sg.com/%{name}/
-AutoReqProv:        no
 
 Requires(pre):          /usr/sbin/useradd
 Requires(pre):          /usr/bin/getent
@@ -20,7 +19,6 @@
 Requires:               sendmail >= 8.12.1
 Requires:               sendmail-cf
 Requires:               spamassassin
-Requires:               libc.so.6, libgcc_s.so.1, libm.so.6, libpthread.so.0, libstdc++.so.6
 
 %description
 We present here a mechanism whereby the backup mail server can use the
@@ -97,7 +95,14 @@
 
 
 %changelog
-* Tue Mar 04 2008 Carl Byington <carl@five-ten-sg.com> - 6.17
+* Tue Jun 10 2008 Carl Byington <carl@five-ten-sg.com> - 6.19-1
+- Fixes to compile on Fedora 9 and for const correctness
+
+* Wed Mar 05 2008 Carl Byington <carl@five-ten-sg.com> - 6.18-1
+- Extend auto-whitelisting when receiving mail even if the auto
+  whitelist is specified in a parent context.
+
+* Tue Mar 04 2008 Carl Byington <carl@five-ten-sg.com> - 6.17-1
 - changes for Fedora packaging guidelines
 
 * Thu Aug 30 2007 Carl Byington <carl@five-ten-sg.com> - 6.07
--- a/src/context.cpp	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/context.cpp	Tue Jun 10 08:58:42 2008 -0700
@@ -18,52 +18,53 @@
 #include <sys/stat.h>
 #include <sys/un.h>
 #include <unistd.h>
+#include <climits>
 
-char *token_autowhite;
-char *token_black;
-char *token_cctld;
-char *token_content;
-char *token_context;
-char *token_dccbulk;
-char *token_dccfrom;
-char *token_dccgrey;
-char *token_dccto;
-char *token_default;
-char *token_dnsbl;
-char *token_dnsbll;
-char *token_envfrom;
-char *token_envto;
-char *token_filter;
-char *token_generic;
-char *token_host_limit;
-char *token_html_limit;
-char *token_html_tags;
-char *token_ignore;
-char *token_include;
-char *token_inherit;
-char *token_lbrace;
-char *token_mailhost;
-char *token_many;
-char *token_no;
-char *token_off;
-char *token_ok;
-char *token_ok2;
-char *token_on;
-char *token_rate;
-char *token_rbrace;
-char *token_require;
-char *token_semi;
-char *token_soft;
-char *token_spamassassin;
-char *token_substitute;
-char *token_tld;
-char *token_unknown;
-char *token_uribl;
-char *token_verify;
-char *token_white;
-char *token_yes;
+const char *token_autowhite;
+const char *token_black;
+const char *token_cctld;
+const char *token_content;
+const char *token_context;
+const char *token_dccbulk;
+const char *token_dccfrom;
+const char *token_dccgrey;
+const char *token_dccto;
+const char *token_default;
+const char *token_dnsbl;
+const char *token_dnsbll;
+const char *token_envfrom;
+const char *token_envto;
+const char *token_filter;
+const char *token_generic;
+const char *token_host_limit;
+const char *token_html_limit;
+const char *token_html_tags;
+const char *token_ignore;
+const char *token_include;
+const char *token_inherit;
+const char *token_lbrace;
+const char *token_mailhost;
+const char *token_many;
+const char *token_no;
+const char *token_off;
+const char *token_ok;
+const char *token_ok2;
+const char *token_on;
+const char *token_rate;
+const char *token_rbrace;
+const char *token_require;
+const char *token_semi;
+const char *token_soft;
+const char *token_spamassassin;
+const char *token_substitute;
+const char *token_tld;
+const char *token_unknown;
+const char *token_uribl;
+const char *token_verify;
+const char *token_white;
+const char *token_yes;
 
-char *token_myhostname;
+const char *token_myhostname;
 #ifndef HOST_NAME_MAX
     #define HOST_NAME_MAX 255
 #endif
@@ -174,7 +175,7 @@
 }
 
 
-int SMTP::cmd(char *c) {
+int SMTP::cmd(const char *c) {
     if (c) {
         init();
         append(c);
@@ -201,7 +202,7 @@
 }
 
 
-int SMTP::from(char *f) {
+int SMTP::from(const char *f) {
     // the mail from address was originally passed in from sendmail enclosed in
     // <>. to_lower_string() removed the <> and converted the rest to lowercase,
     // except in the case of an empty return path, which was left as the two
@@ -219,7 +220,7 @@
 }
 
 
-int SMTP::rcpt(char *t) {
+int SMTP::rcpt(const char *t) {
     init();
     append("RCPT TO:<");
     append(t);
@@ -240,14 +241,14 @@
 
 
 #ifdef VERIFY_DEBUG
-    void SMTP::log(char *m, int v) {
+    void SMTP::log(const char *m, int v) {
         char buf[maxlen];
         snprintf(buf, maxlen, m, v);
         my_syslog(buf);
     }
 
 
-    void SMTP::log(char *m, char *v) {
+    void SMTP::log(const char *m, const char *v) {
         char buf[maxlen];
         snprintf(buf, maxlen, m, v);
         my_syslog(buf);
@@ -258,7 +259,7 @@
 ////////////////////////////////////////////////
 // smtp verifier so backup mx machines can see the valid users
 //
-VERIFY::VERIFY(char *h) {
+VERIFY::VERIFY(const char *h) {
     host     = h;
     last_err = 0;
     pthread_mutex_init(&mutex, 0);
@@ -364,7 +365,7 @@
 }
 
 
-bool VERIFY::ok(char *from, char *to) {
+bool VERIFY::ok(const char *from, const char *to) {
     if (host == token_myhostname) return true;
     SMTP *conn = get_connection();
     if (!conn) return true;    // cannot verify right now, we have socket errors
@@ -390,8 +391,8 @@
 ////////////////////////////////////////////////
 // setup a new smtp verify host
 //
-VERIFYP add_verify_host(char *host);
-VERIFYP add_verify_host(char *host) {
+VERIFYP add_verify_host(const char *host);
+VERIFYP add_verify_host(const char *host) {
     VERIFYP rc = NULL;
     pthread_mutex_lock(&verifier_mutex);
         verify_map::iterator i = verifiers.find(host);
@@ -425,7 +426,7 @@
 ////////////////////////////////////////////////
 // automatic whitelister
 //
-WHITELISTER::WHITELISTER(char *f, int d) {
+WHITELISTER::WHITELISTER(const char *f, int d) {
     fn       = f;
     days     = d;
     pthread_mutex_init(&mutex, 0);
@@ -482,8 +483,8 @@
         for (autowhite_sent::iterator i=rcpts.begin(); i!=rcpts.end();) {
             time_t when = (*i).second;
             if (when < limit) {
-                char *who = (*i).first;
-                free(who);
+                const char *who = (*i).first;
+                free((void*)who);
                 rcpts.erase(i++);
                 need = true;
             }
@@ -496,7 +497,7 @@
             ofs.open(fn);
             if (!ofs.fail()) {
                 for (autowhite_sent::iterator i=rcpts.begin(); i!=rcpts.end(); i++) {
-                    char *who = (*i).first;
+                    const char *who = (*i).first;
                     int  when = (*i).second;
                     if (!strchr(who, ' ')) {
                         ofs << who << " " << when << endl;
@@ -511,7 +512,7 @@
 }
 
 
-void WHITELISTER::sent(char *to) {
+void WHITELISTER::sent(const char *to) {
     // we take ownership of the string
     pthread_mutex_lock(&mutex);
         need = true;
@@ -521,13 +522,13 @@
         }
         else {
             (*i).second = time(NULL);
-            free(to);
+            free((void*)to);
         }
     pthread_mutex_unlock(&mutex);
 }
 
 
-bool WHITELISTER::is_white(char *from) {
+bool WHITELISTER::is_white(const char *from) {
     pthread_mutex_lock(&mutex);
         autowhite_sent::iterator i = rcpts.find(from);
         bool rc = (i != rcpts.end());
@@ -539,8 +540,8 @@
 ////////////////////////////////////////////////
 // setup a new auto whitelister file
 //
-WHITELISTERP add_whitelister_file(char *fn, int days);
-WHITELISTERP add_whitelister_file(char *fn, int days) {
+WHITELISTERP add_whitelister_file(const char *fn, int days);
+WHITELISTERP add_whitelister_file(const char *fn, int days) {
     WHITELISTERP rc = NULL;
     pthread_mutex_lock(&whitelister_mutex);
         whitelister_map::iterator i = whitelisters.find(fn);
@@ -574,14 +575,14 @@
 }
 
 
-DELAYWHITE::DELAYWHITE(char *loto_, WHITELISTERP w_, CONTEXTP con_) {
+DELAYWHITE::DELAYWHITE(const char *loto_, WHITELISTERP w_, CONTEXTP con_) {
     loto = loto_;
     w    = w_;
     con  = con_;
 }
 
 
-DNSBL::DNSBL(char *n, char *s, char *m) {
+DNSBL::DNSBL(const char *n, const char *s, const char *m) {
     name    = n;
     suffix  = s;
     message = m;
@@ -625,7 +626,7 @@
 }
 
 
-void CONFIG::add_to(char *to, CONTEXTP con) {
+void CONFIG::add_to(const char *to, CONTEXTP con) {
     context_map::iterator i = env_to.find(to);
     if (i != env_to.end()) {
         CONTEXTP  c = (*i).second;
@@ -633,8 +634,8 @@
             if (debug_syslog) {
                 char oldname[maxlen];
                 char newname[maxlen];
-                char *oldn = c->get_full_name(oldname, maxlen);
-                char *newn = con->get_full_name(newname, maxlen);
+                const char *oldn = c->get_full_name(oldname, maxlen);
+                const 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);
@@ -645,18 +646,19 @@
 }
 
 
-CONTEXTP CONFIG::find_context(char *to) {
+CONTEXTP CONFIG::find_context(const char *to) {
     context_map::iterator i = env_to.find(to);
     if (i != env_to.end()) return (*i).second;      // found user@domain key
-    char *x = strchr(to, '@');
+    const char *x = strchr(to, '@');
     if (x) {
         x++;
         i = env_to.find(x);
         if (i != env_to.end()) return (*i).second;  // found domain key
-        char y = *x;
-        *x = '\0';
-        i = env_to.find(to);
-        *x = y;
+        size_t len = x - to;
+        char user[len+1];
+        memcpy(user, to, len);
+        user[len] = '\0';
+        i = env_to.find(user);
         if (i != env_to.end()) return (*i).second;  // found user@ key
     }
     return default_context;
@@ -673,7 +675,7 @@
     }
     char buf[maxlen];
     for (context_map::iterator i=env_to.begin(); i!=env_to.end(); i++) {
-        char     *to = (*i).first;
+        const char *to = (*i).first;
         CONTEXTP con = (*i).second;
         printf("// envelope to %s \t-> context %s \n", to, con->get_full_name(buf,maxlen));
     }
@@ -683,7 +685,7 @@
 }
 
 
-CONTEXT::CONTEXT(CONTEXTP parent_, char *name_) {
+CONTEXT::CONTEXT(CONTEXTP parent_, const char *name_) {
     parent              = parent_;
     name                = name_;
     verify_host         = NULL;
@@ -728,7 +730,7 @@
 }
 
 
-char *CONTEXT::get_full_name(char *buffer, int size) {
+const char *CONTEXT::get_full_name(char *buffer, int size) {
     if (!parent) return name;
     char buf[maxlen];
     snprintf(buffer, size, "%s.%s", parent->get_full_name(buf, maxlen), name);
@@ -736,7 +738,7 @@
 }
 
 
-bool CONTEXT::set_generic(char *regx, char *msg)
+bool CONTEXT::set_generic(const char *regx, const char *msg)
 {
     int rc = 0;
     if (generic_regx) regfree(&generic_pattern);
@@ -749,7 +751,7 @@
 }
 
 
-char *CONTEXT::generic_match(char *client)
+const char *CONTEXT::generic_match(const char *client)
 {
     if (!client) return NULL;   // allow missing _ macro, which will disable generic checking
     if (parent && !generic_regx) return parent->generic_match(client);
@@ -761,9 +763,8 @@
 }
 
 
-bool CONTEXT::cover_env_to(char *to) {
-    char buffer[maxlen];
-    char *x = strchr(to, '@');
+bool CONTEXT::cover_env_to(const char *to) {
+    const 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@
@@ -778,7 +779,7 @@
 }
 
 
-VERIFYP CONTEXT::find_verify(char *to) {
+VERIFYP CONTEXT::find_verify(const char *to) {
     if (verifier && (verify_host != token_myhostname) && cover_env_to(to))
         return verifier;
     else if (parent)
@@ -788,7 +789,7 @@
 }
 
 
-WHITELISTERP CONTEXT::find_autowhite(char *from, char *to) {
+WHITELISTERP CONTEXT::find_autowhite(const char *from, const char *to) {
     if (whitelister && cover_env_to(to) && !cover_env_to(from))
         return whitelister;
     else if (parent)
@@ -798,14 +799,14 @@
 }
 
 
-int CONTEXT::find_rate(char *user) {
+int CONTEXT::find_rate(const char *user) {
     if (rcpt_per_hour.empty()) return default_rcpt_rate;
     rcpt_rates::iterator i = rcpt_per_hour.find(user);
     return (i == rcpt_per_hour.end()) ? default_rcpt_rate : (*i).second;
 }
 
 
-char *CONTEXT::find_from(char *from, bool update_white) {
+const char *CONTEXT::find_from(const char *from, bool update_white) {
     WHITELISTERP w = whitelister;
     CONTEXTP     p = parent;
     while (!w && p) {
@@ -825,7 +826,7 @@
         }
         return token_white;
     }
-    char *rc = env_from_default;
+    const char *rc = env_from_default;
     string_map::iterator i = env_from.find(from);
     if (i != env_from.end()) rc = (*i).second;  // found user@domain key
     else {
@@ -848,7 +849,7 @@
 }
 
 
-CONTEXTP CONTEXT::find_context(char *from) {
+CONTEXTP CONTEXT::find_context(const char *from) {
     context_map::iterator i = env_from_context.find(from);
     if (i != env_from_context.end()) return (*i).second;        // found user@domain key
     char *x = strchr(from, '@');
@@ -866,14 +867,14 @@
 }
 
 
-CONTEXTP CONTEXT::find_from_context_name(char *name) {
+CONTEXTP CONTEXT::find_from_context_name(const char *name) {
     context_map::iterator i = children.find(name);
     if (i != children.end()) return (*i).second;
     return NULL;
 }
 
 
-DNSBLP CONTEXT::find_dnsbl(char *name) {
+DNSBLP CONTEXT::find_dnsbl(const char *name) {
     dnsblp_map::iterator i = dnsbl_names.find(name);
     if (i != dnsbl_names.end()) return (*i).second;
     if (parent) return parent->find_dnsbl(name);
@@ -881,25 +882,25 @@
 }
 
 
-char* CONTEXT::get_content_suffix() {
+const char* CONTEXT::get_content_suffix() {
     if (!content_suffix && parent) return parent->get_content_suffix();
     return content_suffix;
 }
 
 
-char* CONTEXT::get_uribl_suffix() {
+const char* CONTEXT::get_uribl_suffix() {
     if (!uribl_suffix && parent) return parent->get_uribl_suffix();
     return uribl_suffix;
 }
 
 
-char* CONTEXT::get_content_message() {
+const char* CONTEXT::get_content_message() {
     if (!content_message && parent) return parent->get_content_message();
     return content_message;
 }
 
 
-char* CONTEXT::get_uribl_message() {
+const char* CONTEXT::get_uribl_message() {
     if (!uribl_message && parent) return parent->get_uribl_message();
     return uribl_message;
 }
@@ -965,11 +966,11 @@
     memset(indent, ' ', i);
     indent[i] = '\0';
     char buf[maxlen];
-    char *fullname = get_full_name(buf,maxlen);
+    const 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;
+        const char *n = (*i).first;
         DNSBL &d = *(*i).second;
         printf("%s     dnsbl %s %s \"%s\"; \n", indent, n, d.suffix, d.message);
     }
@@ -985,7 +986,7 @@
     }
 
     if (content_filtering) {
-        printf("%s     content on { \n", indent, env_from_default);
+        printf("%s     content on { \n", indent);
         if (content_suffix) {
             printf("%s         filter %s \"%s\"; \n", indent, content_suffix, content_message);
         }
@@ -1048,7 +1049,7 @@
         spamass |= (spamassassin_limit != 0);
         }
     else {
-        printf("%s     content off {}; \n", indent, env_from_default);
+        printf("%s     content off {}; \n", indent);
     }
 
     printf("%s     env_to { \t// %s\n", indent, fullname);
@@ -1079,15 +1080,15 @@
     if (!env_from.empty()) {
         printf("%s     // white/black/unknown \n", indent);
         for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) {
-            char *f = (*i).first;
-            char *t = (*i).second;
+            const char *f = (*i).first;
+            const char *t = (*i).second;
             printf("%s         %s \t%s; \n", indent, f, t);
         }
     }
     if (!env_from_context.empty()) {
         printf("%s     // child contexts \n", indent);
         for (context_map::iterator j=env_from_context.begin(); j!=env_from_context.end(); j++) {
-            char    *f = (*j).first;
+            const char    *f = (*j).first;
             CONTEXTP t = (*j).second;
             printf("%s         %s \t%s; \n", indent, f, t->name);
         }
@@ -1097,7 +1098,7 @@
     if (isdefault) {
         printf("%s     rate_limit %d { \n", indent, default_rcpt_rate);
         for (rcpt_rates::iterator j=rcpt_per_hour.begin(); j!=rcpt_per_hour.end(); j++) {
-            char    *u = (*j).first;
+            const char *u = (*j).first;
             int      l = (*j).second;
             printf("%s         \"%s\" \t%d; \n", indent, u, l);
         }
@@ -1113,7 +1114,7 @@
 //
 void discard(string_set &s) {
     for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
-        free(*i);
+        free((void*)*i);
     }
     s.clear();
 }
@@ -1122,7 +1123,7 @@
 ////////////////////////////////////////////////
 // helper to register a string in a string set
 //
-char* register_string(string_set &s, char *name) {
+const char* register_string(string_set &s, const char *name) {
     string_set::iterator i = s.find(name);
     if (i != s.end()) return *i;
     char *x = strdup(name);
@@ -1134,7 +1135,7 @@
 ////////////////////////////////////////////////
 // register a global string
 //
-char* register_string(char *name) {
+const char* register_string(const char *name) {
     return register_string(all_strings, name);
 }
 
@@ -1149,9 +1150,9 @@
 
 ////////////////////////////////////////////////
 //
-bool tsa(TOKEN &tok, char *token);
-bool tsa(TOKEN &tok, char *token) {
-    char *have = tok.next();
+bool tsa(TOKEN &tok, const char *token);
+bool tsa(TOKEN &tok, const char *token) {
+    const char *have = tok.next();
     if (have == token) return true;
     tok.token_error(token, have);
     return false;
@@ -1162,9 +1163,9 @@
 //
 bool parse_dnsbl(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_dnsbl(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
-    char *name = tok.next();
-    char *suf = tok.next();
-    char *msg = tok.next();
+    const char *name = tok.next();
+    const char *suf  = tok.next();
+    const char *msg  = tok.next();
     if (!tsa(tok, token_semi)) return false;
     DNSBLP dnsnew = new DNSBL(name, suf, msg);
     DNSBLP dnsold = me.find_dnsbl(name);
@@ -1183,7 +1184,7 @@
 bool parse_dnsbll(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_dnsbll(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
     while (true) {
-        char *have = tok.next();
+        const char *have = tok.next();
         if (!have) break;
         if (have == token_semi) break;
         DNSBLP dns = me.find_dnsbl(have);
@@ -1203,7 +1204,7 @@
 //
 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_content(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
-    char *setting = tok.next();
+    const char *setting = tok.next();
     if (setting == token_on) {
         me.set_content_filtering(true);
     }
@@ -1216,18 +1217,18 @@
     }
     if (!tsa(tok, token_lbrace)) return false;
     while (true) {
-        char *have = tok.next();
+        const char *have = tok.next();
         if (!have) break;
         if (have == token_filter) {
-            char *suffix = tok.next();
-            char *messag = tok.next();
+            const char *suffix = tok.next();
+            const char *messag = tok.next();
             me.set_content_suffix(suffix);
             me.set_content_message(messag);
             if (!tsa(tok, token_semi)) return false;
         }
         else if (have == token_uribl) {
-            char *suffix = tok.next();
-            char *messag = tok.next();
+            const char *suffix = tok.next();
+            const char *messag = tok.next();
             me.set_uribl_suffix(suffix);
             me.set_uribl_message(messag);
             if (!tsa(tok, token_semi)) return false;
@@ -1236,7 +1237,7 @@
             if (!tsa(tok, token_lbrace)) return false;
             while (true) {
                 if (!have) break;
-                char *have = tok.next();
+                const char *have = tok.next();
                 if (have == token_rbrace) break;  // done
                 me.add_ignore(have);
             }
@@ -1245,7 +1246,7 @@
         else if (have == token_tld) {
             if (!tsa(tok, token_lbrace)) return false;
             while (true) {
-                char *have = tok.next();
+                const char *have = tok.next();
                 if (!have) break;
                 if (have == token_rbrace) break;  // done
                 me.add_tld(have);
@@ -1255,7 +1256,7 @@
         else if (have == token_cctld) {
             if (!tsa(tok, token_lbrace)) return false;
             while (true) {
-                char *have = tok.next();
+                const char *have = tok.next();
                 if (!have) break;
                 if (have == token_rbrace) break;  // done
                 me.add_cctld(have);
@@ -1265,7 +1266,7 @@
         else if (have == token_html_tags) {
             if (!tsa(tok, token_lbrace)) return false;
             while (true) {
-                char *have = tok.next();
+                const char *have = tok.next();
                 if (!have) break;
                 if (have == token_rbrace) {
                     break;  // done
@@ -1377,18 +1378,18 @@
 bool parse_envto(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
     if (!tsa(tok, token_lbrace)) return false;
     while (true) {
-        char *have = tok.next();
+        const char *have = tok.next();
         if (!have) break;
         if (have == token_rbrace) break;
         if (have == token_semi) {
             // optional separators
         }
         else if (have == token_dccto) {
-            char *flavor = tok.next();
+            const char *flavor = tok.next();
             if (!tsa(tok, token_lbrace)) return false;
             bool keeping = false;
             while (true) {
-                char *have = tok.next();
+                const char *have = tok.next();
                 if (!have) break;
                 if (have == token_rbrace) break;
                 if (have == flavor) {
@@ -1439,7 +1440,7 @@
 //
 bool parse_verify(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_verify(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
-    char *host = tok.next();
+    const char *host = tok.next();
     if (!tsa(tok, token_semi)) return false;
     me.set_verify(host);
     me.set_verifier(add_verify_host(host));
@@ -1451,8 +1452,8 @@
 //
 bool parse_generic(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_generic(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
-    char *regx = tok.next();
-    char *msg  = tok.next();
+    const char *regx = tok.next();
+    const char *msg  = tok.next();
     if (!tsa(tok, token_semi)) return false;
     if (me.set_generic(regx, msg)) {
         tok.token_error("invalid regular expression %s", regx, regx);
@@ -1467,7 +1468,7 @@
 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
     int days = tok.nextint();
-    char *fn = tok.next();
+    const char *fn = tok.next();
     if (!tsa(tok, token_semi)) return false;
     me.set_autowhite(fn);
     me.set_whitelister(add_whitelister_file(fn, days));
@@ -1479,7 +1480,7 @@
 //
 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_envfrom(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
-    char *st = tok.next();
+    const char *st = tok.next();
     if ((st == token_black) || (st == token_white) || (st == token_unknown) || (st == token_inherit)) {
         me.set_from_default(st);
     }
@@ -1488,7 +1489,7 @@
     }
     if (!tsa(tok, token_lbrace)) return false;
     while (true) {
-        char *have = tok.next();
+        const char *have = tok.next();
         if (!have) break;
         if (have == token_rbrace) break;
         if (have == token_semi) {
@@ -1499,7 +1500,7 @@
             bool keeping = false;
             bool many = false;
             while (true) {
-                char *have = tok.next();
+                const char *have = tok.next();
                 if (!have) break;
                 if (have == token_rbrace) break;
                 if (have == token_ok) {
@@ -1533,7 +1534,7 @@
         }
         else {
             // may be a valid email address or domain name
-            char *st = tok.next();
+            const char *st = tok.next();
             if ((st == token_white) || (st == token_black) || (st == token_unknown) || (st == token_inherit)) {
                 me.add_from(have, st);
             }
@@ -1557,12 +1558,12 @@
 //
 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_rate(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
-    char *def = tok.next();
+    const char *def = tok.next();
     tok.push(def);
     if (def != token_lbrace) me.set_default_rate(tok.nextint());
     if (!tsa(tok, token_lbrace)) return false;
     while (true) {
-        char *have = tok.next();
+        const char *have = tok.next();
         if (!have) break;
         if (have == token_rbrace) break;
         if (have == token_semi) {
@@ -1580,12 +1581,12 @@
 //
 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent);
 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent) {
-    char *name = tok.next();
+    const char *name = tok.next();
     if (!tsa(tok, token_lbrace)) return false;
     CONTEXTP con = new CONTEXT(parent, name);
 
     while (true) {
-        char *have = tok.next();
+        const char *have = tok.next();
         if (!have) break;
         if (have == token_rbrace) break;  // done
         if (have == token_dnsbl) {
@@ -1638,11 +1639,11 @@
 ////////////////////////////////////////////////
 // parse a config file
 //
-bool load_conf(CONFIG &dc, char *fn) {
+bool load_conf(CONFIG &dc, const char *fn) {
     int count = 0;
     TOKEN tok(fn, &dc.config_files);
     while (true) {
-        char *have = tok.next();
+        const char *have = tok.next();
         if (!have) break;
         if (have == token_context) {
             if (!parse_context(tok, dc, NULL)) {
--- a/src/context.h	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/context.h	Tue Jun 10 08:58:42 2008 -0700
@@ -9,11 +9,6 @@
 #ifndef context_include
 #define context_include
 
-#include "tokenizer.h"
-#include <map>
-#include <regex.h>
-
-
 enum status {oksofar,		// not rejected yet
 			 white, 		// whitelisted
 			 black, 		// blacklisted
@@ -27,24 +22,23 @@
 class DELAYWHITE;
 class recorder;
 
-typedef map<char *, char *, ltstr>		  string_map;
+typedef map<const char *, const char *, ltstr>  string_map;
 typedef set<int>						  int_set;
 typedef list<SMTP *>					  smtp_list;
-typedef list<char *>					  string_list;
 typedef DNSBL * 						  DNSBLP;
 typedef VERIFY *						  VERIFYP;
 typedef WHITELISTER *					  WHITELISTERP;
 typedef DELAYWHITE *                      DELAYWHITEP;
 typedef list<DNSBLP>					  dnsblp_list;
-typedef map<char *, DNSBLP, ltstr>		  dnsblp_map;
+typedef map<const char *, DNSBLP, ltstr>        dnsblp_map;
 typedef CONTEXT *						  CONTEXTP;
 typedef list<CONTEXTP>					  context_list;
-typedef map<char *, CONTEXTP, ltstr>	  context_map;
-typedef map<char *, int, ltstr> 		  ns_mapper;
-typedef map<char *, int, ltstr> 		  rcpt_rates;
-typedef map<char *, time_t,  ltstr> 	  autowhite_sent;
-typedef map<char *, VERIFYP, ltstr> 	  verify_map;
-typedef map<char *, WHITELISTERP, ltstr>  whitelister_map;
+typedef map<const char *, CONTEXTP, ltstr>      context_map;
+typedef map<const char *, int, ltstr>           ns_mapper;
+typedef map<const char *, int, ltstr>           rcpt_rates;
+typedef map<const char *, time_t,  ltstr>       autowhite_sent;
+typedef map<const char *, VERIFYP, ltstr>       verify_map;
+typedef map<const char *, WHITELISTERP, ltstr>  whitelister_map;
 typedef list<DELAYWHITEP>                 delay_whitelist;
 
 class SMTP {
@@ -59,7 +53,7 @@
 	SMTP(int f) 			{fd = f; error = false; now(); efrom[0] = '\0'; init();};
 	~SMTP() 				{if (!error) quit(); closefd();};
 	void	init()			{pending = 0; buffer[0] = '\0';};
-	void	append(char *c) {strncat(buffer, c, max(0, maxlen-1-(int)strlen(c)));};
+    void    append(const char *c)   {strncat(buffer, c, max(0, maxlen-1-(int)strlen(c)));};
 	bool	err()			{return error;};
 	void	now()			{stamp = time(NULL);};
 	time_t	get_stamp() 	{return stamp;};
@@ -69,97 +63,97 @@
 	int 	read_line();
 	int 	read_response();
 	void	flush_line(int r);
-	int 	cmd(char *c);
+    int     cmd(const char *c);
 	int 	helo();
 	int 	rset();
-	int 	from(char *f);
-	int 	rcpt(char *t);
+    int     from(const char *f);
+    int     rcpt(const char *t);
 	int 	quit();
 	void	closefd();
 #ifdef VERIFY_DEBUG
-	static void log(char *m, int v);
-	static void log(char *m, char *v);
+    static void log(const char *m, int v);
+    static void log(const char *m, const char *v);
 #endif
 };
 
 class VERIFY {
-	char			*host;		// host to be used to verify recipient addresses
+    const char      *host;      // host to be used to verify recipient addresses
 	time_t			last_err;	// time of last socket error
 	pthread_mutex_t mutex;		// protect the lists of sockets and timestamps
 	smtp_list		connections;// open sockets, ready to be used
 public:
-	VERIFY(char *h);
+    VERIFY(const char *h);
 	void	closer();			// if the oldest socket is ancient, close it
 	SMTP	*get_connection();
 	void	put_connection(SMTP *conn);
-	bool	ok(char *from, char *to);
+    bool    ok(const char *from, const char *to);
 };
 
 class WHITELISTER {
-	char			*fn;		// file to use
+    const char      *fn;        // file to use
 	int 			days;		// how long do we keep entries
 	pthread_mutex_t mutex;		// protect the flag and map
 	time_t			loaded; 	// when we loaded this file
 	bool			need;		// force writing on new entries
 	autowhite_sent	rcpts;		// recipient map to remember when we sent them mail
 public:
-	WHITELISTER(char *f, int d);
+    WHITELISTER(const char *f, int d);
 	void	merge();
 	void	writer();			// dump any changes back to the file
-	void	sent(char *to);
-	bool	is_white(char *from);	// should we white list this sender (did we send them anything recently)
+    void    sent(const char *to);
+    bool    is_white(const char *from); // should we white list this sender (did we send them anything recently)
 	int 	get_days()		{return days;};
 	void	set_days(int d) {days = d;};
 };
 
 class DELAYWHITE {
-    char*           loto;
+    const char     *loto;
     WHITELISTERP    w;
     CONTEXTP        con;
 public:
-    DELAYWHITE(char *loto_, WHITELISTERP w_, CONTEXTP con_);
-    char           *get_loto() {return loto;};
+    DELAYWHITE(const char *loto_, WHITELISTERP w_, CONTEXTP con_);
+    const char     *get_loto() {return loto;};
     WHITELISTERP    get_w()    {return w;};
     CONTEXTP        get_con()  {return con;};
 };
 
 struct DNSBL {
-	char	*name;		// nickname for this dns based list
-	char	*suffix;	// blacklist suffix like blackholes.five-ten-sg.com
-	char	*message;	// error message with one or two %s operators for the ip address replacement
-	DNSBL(char *n, char *s, char *m);
+    const char    *name;    // nickname for this dns based list
+    const char    *suffix;  // blacklist suffix like blackholes.five-ten-sg.com
+    const char    *message; // error message with one or two %s operators for the ip address replacement
+    DNSBL(const char *n, const char *s, const char *m);
 	bool operator==(const DNSBL &rhs);
 };
 
 class CONTEXT {
 	CONTEXTP		parent;
-	char *			name;
+    const char *    name;
 	context_map 	children;			// map child context names to their contexts
 	string_set		env_to; 			// this context applies to these envelope recipients
-	char *			verify_host;		// use this smtp host to verify email addresses
+    const char *    verify_host;        // use this smtp host to verify email addresses
 	VERIFYP 		verifier;			// pointer to the verifier structure
-	char *			generic_regx;		// pointer to generic regular expression
-	char *			generic_message;	// pointer to generic message with one %s
+    const char *    generic_regx;       // pointer to generic regular expression
+    const char *    generic_message;    // pointer to generic message with one %s
 	regex_t 		generic_pattern;	// compiled regex pattern
-	char *			autowhite_file; 	// file to use for automatic whitelisting
+    const char *    autowhite_file;     // file to use for automatic whitelisting
 	WHITELISTERP	whitelister;		// pointer to the auto whitelister structure
 	string_map		env_from;			// map senders to white/black/unknown
 	context_map 	env_from_context;	// map senders to a child context
-	char *			env_from_default;	// default value for senders that are not found in the map white/black/unknown/inherit
+    const char *    env_from_default;   // default value for senders that are not found in the map white/black/unknown/inherit
 	bool			content_filtering;	//
-	char *			content_suffix; 	// for url body filtering based on ip addresses of hostnames in the body
-	char *			content_message;	// ""
-	char *			uribl_suffix;		// for uribl body filtering based on hostnames in the body
-	char *			uribl_message;		// ""
+    const char *    content_suffix;     // for url body filtering based on ip addresses of hostnames in the body
+    const char *    content_message;    // ""
+    const char *    uribl_suffix;       // for uribl body filtering based on hostnames in the body
+    const char *    uribl_message;      // ""
 	string_set		content_host_ignore;// hosts to ignore for content sbl checking
 	string_set		content_tlds;		//
 	string_set		content_cctlds; 	//
 	string_set		html_tags;			// set of valid html tags
 	int 			host_limit; 		// limit on host names
-	char *			host_limit_message; // error message for excessive host names
+    const char *    host_limit_message; // error message for excessive host names
 	bool			host_random;		// pick a random selection of host names rather than error for excessive hosts
 	int 			tag_limit;			// limit on bad html tags
-	char *			tag_limit_message;	// error message for excessive bad html tags
+    const char *    tag_limit_message;  // error message for excessive bad html tags
 	int 			spamassassin_limit; // max score from spamassassin
 	bool			require_match;		// require matching context filtering context
 	bool			dcc_greylist;		// should we do dcc greylisting?
@@ -171,61 +165,61 @@
 
 
 public:
-	CONTEXT(CONTEXTP parent_, char *name_);
+    CONTEXT(CONTEXTP parent_, const char *name_);
 	~CONTEXT();
 	CONTEXTP	get_parent()								{return parent;};
 	bool		is_parent(CONTEXTP p);		// is p a parent of this?
-	char*		get_full_name(char *buf, int size);
+    const char* get_full_name(char *buffer, int size);
 	void		add_context(CONTEXTP child) 				{children[child->name] = child;};
-	bool		allow_env_to(char *to)						{return (parent) ? parent->cover_env_to(to) : true;};
-	bool		cover_env_to(char *to);
+    bool        allow_env_to(const char *to)                {return (parent) ? parent->cover_env_to(to) : true;};
+    bool        cover_env_to(const char *to);
 
 	void		set_verifier(VERIFYP v) 					{verifier	 = v;};
-	void		set_verify(char *host)						{verify_host = host;};
-	char*		get_verify()								{return verify_host;};
-	VERIFYP 	find_verify(char *to);
+    void        set_verify(const char *host)                {verify_host = host;};
+    const char* get_verify()                                {return verify_host;};
+    VERIFYP     find_verify(const char *to);
 
 
 	void		set_whitelister(WHITELISTERP v) 			{whitelister	= v;};
-	void		set_autowhite(char *fn) 					{autowhite_file = fn;};
-	char*		get_autowhite() 							{return autowhite_file;};
-	WHITELISTERP find_autowhite(char *from, char *to);
+    void        set_autowhite(const char *fn)               {autowhite_file = fn;};
+    const char* get_autowhite()                             {return autowhite_file;};
+    WHITELISTERP find_autowhite(const char *from, const char *to);
 
 	void		set_default_rate(int limit) 				{default_rcpt_rate	 = limit;};
-	void		add_rate(char *user, int limit) 			{rcpt_per_hour[user] = limit;};
-	int 		find_rate(char *user);
+    void        add_rate(const char *user, int limit)       {rcpt_per_hour[user] = limit;};
+    int         find_rate(const char *user);
 
-	void		add_to(char *to)							{env_to.insert(to);};
-	void		add_from(char *from, char *status)			{env_from[from] = status;};
-	void		add_from_context(char *from, CONTEXTP con)	{env_from_context[from] = con;};
-	void		set_from_default(char *status)				{env_from_default = status;};
-	char*		find_from(char *from, bool update_white = false);
-	CONTEXTP	find_context(char *from);
-	CONTEXTP	find_from_context_name(char *name);
+    void        add_to(const char *to)                            {env_to.insert(to);};
+    void        add_from(const char *from, const char *status)    {env_from[from] = status;};
+    void        add_from_context(const char *from, CONTEXTP con)  {env_from_context[from] = con;};
+    void        set_from_default(const char *status)              {env_from_default = status;};
+    const char* find_from(const char *from, bool update_white = false);
+    CONTEXTP    find_context(const char *from);
+    CONTEXTP    find_from_context_name(const char *name);
 
 	void		set_content_filtering(bool filter)			{content_filtering = filter;	  };
-	void		set_content_suffix(char *suffix)			{content_suffix    = suffix;	  };
-	void		set_content_message(char *message)			{content_message   = message;	  };
-	void		set_uribl_suffix(char *suffix)				{uribl_suffix	   = suffix;	  };
-	void		set_uribl_message(char *message)			{uribl_message	   = message;	  };
-	void		add_ignore(char *host)						{content_host_ignore.insert(host);};
-	void		add_tld(char *tld)							{content_tlds.insert(tld);		  };
-	void		add_cctld(char *cctld)						{content_cctlds.insert(cctld);	  };
+    void        set_content_suffix(const char *suffix)      {content_suffix    = suffix;      };
+    void        set_content_message(const char *message)    {content_message   = message;     };
+    void        set_uribl_suffix(const char *suffix)        {uribl_suffix      = suffix;      };
+    void        set_uribl_message(const char *message)      {uribl_message     = message;     };
+    void        add_ignore(const char *host)                {content_host_ignore.insert(host);};
+    void        add_tld(const char *tld)                    {content_tlds.insert(tld);        };
+    void        add_cctld(const char *cctld)                {content_cctlds.insert(cctld);    };
 
 	void		set_host_limit(int limit)					{host_limit 		= limit;  };
-	void		set_host_message(char *message) 			{host_limit_message = message;};
+    void        set_host_message(const char *message)       {host_limit_message = message;};
 	void		set_host_random(bool random)				{host_random		= random; };
 	void		set_spamassassin_limit(int limit)			{spamassassin_limit = limit;  };
 	void		set_tag_limit(int limit)					{tag_limit			= limit;  };
-	void		set_tag_message(char *message)				{tag_limit_message	= message;};
-	void		add_tag(char *tag)							{html_tags.insert(tag); 	  };
+    void        set_tag_message(const char *message)        {tag_limit_message  = message;};
+    void        add_tag(const char *tag)                    {html_tags.insert(tag);       };
 
-	void		add_dnsbl(char *name, DNSBLP dns)			{dnsbl_names[name] = dns;  };
+    void        add_dnsbl(const char *name, DNSBLP dns)     {dnsbl_names[name] = dns;  };
 	void		add_dnsbl(DNSBLP dns)						{dnsbl_list.push_back(dns);};
-	DNSBLP		find_dnsbl(char *name);
+    DNSBLP      find_dnsbl(const char *name);
 
-	bool		set_generic(char *regx, char *msg);
-	char*		generic_match(char *client);
+    bool        set_generic(const char *regx, const char *msg);
+    const char* generic_match(const char *client);
 
 	void		set_require(bool r) 						{require_match		= r; };
 	void		set_grey(bool g)							{dcc_greylist		= g; };
@@ -238,10 +232,10 @@
 	int 			get_host_limit()						{return (content_filtering) ? host_limit		 : 0;};
 	bool			get_host_random()						{return (content_filtering) ? host_random		 : 0;};
 	int 			get_spamassassin_limit()				{return (content_filtering) ? spamassassin_limit : 0;};
-	char*			get_content_suffix();
-	char*			get_content_message();
-	char*			get_uribl_suffix();
-	char*			get_uribl_message();
+    const char*     get_content_suffix();
+    const char*     get_content_message();
+    const char*     get_uribl_suffix();
+    const char*     get_uribl_message();
 	string_set& 	get_content_host_ignore();
 	string_set& 	get_content_tlds();
 	string_set& 	get_content_cctlds();
@@ -249,7 +243,7 @@
 	dnsblp_list&	get_dnsbl_list();
 
 	bool		acceptable_content(recorder &memory, int score, int bulk, string& msg);
-	bool		ignore_host(char *host);
+    bool        ignore_host(const char *host);
 
 	void		dump(bool isdefault, bool &spamass, int level = 0);
 };
@@ -270,65 +264,64 @@
 	CONFIG();
 	~CONFIG();
 	void		add_context(CONTEXTP con);
-	void		add_to(char *to, CONTEXTP con);
-	CONTEXTP	find_context(char *to);
+    void        add_to(const char *to, CONTEXTP con);
+    CONTEXTP    find_context(const char *to);
 	void		dump();
 };
 
 
-extern char *token_autowhite;
-extern char *token_black;
-extern char *token_cctld;
-extern char *token_content;
-extern char *token_context;
-extern char *token_dccbulk;
-extern char *token_dccfrom;
-extern char *token_dccgrey;
-extern char *token_dccto;
-extern char *token_default;
-extern char *token_dnsbl;
-extern char *token_dnsbll;
-extern char *token_envfrom;
-extern char *token_envto;
-extern char *token_filter;
-extern char *token_generic;
-extern char *token_host_limit;
-extern char *token_html_limit;
-extern char *token_html_tags;
-extern char *token_ignore;
-extern char *token_include;
-extern char *token_inherit;
-extern char *token_lbrace;
-extern char *token_mailhost;
-extern char *token_many;
-extern char *token_no;
-extern char *token_off;
-extern char *token_ok;
-extern char *token_ok2;
-extern char *token_on;
-extern char *token_rate;
-extern char *token_rbrace;
-extern char *token_require;
-extern char *token_semi;
-extern char *token_soft;
-extern char *token_spamassassin;
-extern char *token_substitute;
-extern char *token_tld;
-extern char *token_unknown;
-extern char *token_uribl;
-extern char *token_verify;
-extern char *token_white;
-extern char *token_yes;
+extern const char *token_autowhite;
+extern const char *token_black;
+extern const char *token_cctld;
+extern const char *token_content;
+extern const char *token_context;
+extern const char *token_dccbulk;
+extern const char *token_dccfrom;
+extern const char *token_dccgrey;
+extern const char *token_dccto;
+extern const char *token_default;
+extern const char *token_dnsbl;
+extern const char *token_dnsbll;
+extern const char *token_envfrom;
+extern const char *token_envto;
+extern const char *token_filter;
+extern const char *token_generic;
+extern const char *token_host_limit;
+extern const char *token_html_limit;
+extern const char *token_html_tags;
+extern const char *token_ignore;
+extern const char *token_include;
+extern const char *token_inherit;
+extern const char *token_lbrace;
+extern const char *token_mailhost;
+extern const char *token_many;
+extern const char *token_no;
+extern const char *token_off;
+extern const char *token_ok;
+extern const char *token_ok2;
+extern const char *token_on;
+extern const char *token_rate;
+extern const char *token_rbrace;
+extern const char *token_require;
+extern const char *token_semi;
+extern const char *token_soft;
+extern const char *token_spamassassin;
+extern const char *token_substitute;
+extern const char *token_tld;
+extern const char *token_unknown;
+extern const char *token_uribl;
+extern const char *token_verify;
+extern const char *token_white;
+extern const char *token_yes;
 
 extern pthread_mutex_t verifier_mutex;	   // protect the verifier map
 extern pthread_mutex_t whitelister_mutex;  // protect the
 
 void discard(string_set &s);
-char* register_string(string_set &s, char *name);
-char* register_string(char *name);
+const char* register_string(string_set &s, const char *name);
+const char* register_string(const char *name);
 void  clear_strings();
-CONFIG *parse_config(char *fn);
-bool  load_conf(CONFIG &dc, char *fn);
+bool  load_conf(CONFIG &dc, const char *fn);
 void* verify_closer(void *arg);
 void* whitelister_writer(void *arg);
 void  token_init();
--- a/src/dccifd.cpp	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/dccifd.cpp	Tue Jun 10 08:58:42 2008 -0700
@@ -52,7 +52,7 @@
 }
 
 
-DccInterface::DccInterface(char *port_, mlfiPriv *priv_, int ip, char *helo_, char *from)
+DccInterface::DccInterface(const char *port_, mlfiPriv *priv_, int ip, const char *helo_, const char *from)
 {
 	err 			= false;
 	first_recipient = true;
@@ -72,7 +72,7 @@
 }
 
 
-void DccInterface::mlfi_envrcpt(SMFICTX *ctx, char *envrcpt, bool grey)
+void DccInterface::mlfi_envrcpt(SMFICTX *ctx, const char *envrcpt, bool grey)
 {
 	if (first_recipient) {
 		first_recipient = false;
@@ -80,7 +80,7 @@
 		adr[0] = '\0';
 		inet_ntop(AF_INET, (const u_char *)&ip4, adr, sizeof(adr));
 		// Validated sending site's address
-		char *rdns = getmacro(ctx, "_", "");
+		const char *rdns = getmacro(ctx, "_", "");
 		char buf[maxlen+1];
 		if (*rdns == '[') rdns = "";
 		else {
@@ -93,7 +93,6 @@
 		output(options);
 		output(adr);		output("\r");
 		output(rdns);		output("\n");
-		//output("4.3.2.1\r\n");  // !! not local whitelisting
 		output(helo);		output("\n");
 		output(envfrom);	output("\n");
 	}
@@ -103,7 +102,7 @@
 }
 
 
-void DccInterface::mlfi_header(SMFICTX *ctx, char* headerf, char* headerv)
+void DccInterface::mlfi_header(SMFICTX *ctx, const char *headerf, const char *headerv)
 {
 	if (dccifd_socket == NULL_SOCKET) Connect();
 	if ((dccifd_socket != NULL_SOCKET) && (!dccifd_input.empty())) {
@@ -129,9 +128,9 @@
 }
 
 
-void DccInterface::mlfi_body(u_char *bodyp, size_t bodylen)
+void DccInterface::mlfi_body(const u_char *bodyp, size_t bodylen)
 {
-	output((char *)bodyp, bodylen);
+	output((const char *)bodyp, bodylen);
 }
 
 
@@ -317,7 +316,7 @@
 	if ((dccifd_socket == NULL_SOCKET) || err) return;
 	char buf[maxlen];
 	int rs;
-	while (rs = my_read(buf, maxlen)) {
+	while ((rs = my_read(buf, maxlen))) {
 		//my_syslog(priv, string("dcc read ") + escaper(string(buf, rs)));
 		dccifd_output.append(buf, rs);
 	}
@@ -325,9 +324,9 @@
 }
 
 
-char *DccInterface::getmacro(SMFICTX *ctx, char *macro, char *def)
+const char *DccInterface::getmacro(SMFICTX *ctx, const char *macro, const char *def)
 {
-	char *rc = smfi_getsymval(ctx, macro);
+	const char *rc = smfi_getsymval(ctx, (char*)macro);
 	if (!rc) rc = def;
 	return rc;
 }
--- a/src/dccifd.h	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/dccifd.h	Tue Jun 10 08:58:42 2008 -0700
@@ -25,13 +25,13 @@
 
 class DccInterface {
 public:
-	DccInterface(char *port_, mlfiPriv *priv_, int ip, char *helo_, char *from);
+    DccInterface(const char *port_, mlfiPriv *priv_, int ip, const char *helo_, const char *from);
 	~DccInterface();
 
-	void mlfi_envrcpt(SMFICTX *ctx, char *envrcpt, bool grey);
-	void mlfi_header(SMFICTX *ctx, char* headerf, char* headerv);
+    void mlfi_envrcpt(SMFICTX *ctx, const char *envrcpt, bool grey);
+    void mlfi_header(SMFICTX *ctx, const char *headerf, const char *headerv);
 	void mlfi_eoh();
-	void mlfi_body(u_char *bodyp, size_t bodylen);
+    void mlfi_body(const u_char *bodyp, size_t bodylen);
 	void mlfi_eom(bool &grey, int &bulk);
 
 private:
@@ -44,7 +44,7 @@
 	void output(string buffer);
 	void close_output();
 	void input();
-	char *getmacro(SMFICTX *ctx, char *macro, char *def);
+    const char *getmacro(SMFICTX *ctx, const char *macro, const char *def);
 
 public:
 	bool err;				// socket write error
@@ -56,12 +56,12 @@
 	int 	 ip4;		// ip4 address of smtp client
 
 	// strings owned by main dnsbl
-	char *helo; 		// client helo value
-	char *envfrom;		// envelope from value for this message
+    const char *helo;       // client helo value
+    const char *envfrom;    // envelope from value for this message
 
 	// Process handling variables
 	int    dccifd_socket;
-	char  *dccifd_port;
+    const char  *dccifd_port;
 	string dccifd_output;	// to dccifd socket
 	string dccifd_input;	// from dccifd socket
 };
--- a/src/dnsbl.cpp	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/dnsbl.cpp	Tue Jun 10 08:58:42 2008 -0700
@@ -95,9 +95,9 @@
 std::set<int>    fd_pool;
 int         NULL_SOCKET              = -1;
 const       time_t ERROR_SOCKET_TIME = 60;          // number of seconds between attempts to open a socket to the dns resolver process
-char       *resolver_port            = NULL;        // unix domain socket to talk to the dns resolver process
+const char *resolver_port            = NULL;        // unix domain socket to talk to the dns resolver process
 int         resolver_socket          = NULL_SOCKET; // socket used to listen for resolver requests
-char       *dccifd_port              = NULL;        // unix domain socket to talk to the dcc interface daemon
+const char *dccifd_port              = NULL;        // unix domain socket to talk to the dcc interface daemon
 time_t      last_error_time;
 int         resolver_sock_count = 0;        // protected with fd_pool_mutex
 int         resolver_pool_size  = 0;        // protected with fd_pool_mutex
@@ -109,23 +109,23 @@
     string_map  ns_host;    // nameserver name -> host name that uses this name server
     ns_mapper   ns_ip;      // nameserver name -> ip address of the name server
     ~ns_map();
-    void add(char *name, char *refer);
+    void add(const char *name, const char *refer);
 };
 
 
 ns_map::~ns_map() {
     for (string_map::iterator i=ns_host.begin(); i!=ns_host.end(); i++) {
-        char *x = (*i).first;
-        char *y = (*i).second;
-        free(x);
-        free(y);
+        const char *x = (*i).first;
+        const char *y = (*i).second;
+        free((void*)x);
+        free((void*)y);
     }
     ns_ip.clear();
     ns_host.clear();
 }
 
 
-void ns_map::add(char *name, char *refer) {
+void ns_map::add(const char *name, const char *refer) {
     string_map::iterator i = ns_host.find(name);
     if (i != ns_host.end()) return;
     char *x = strdup(name);
@@ -138,7 +138,7 @@
 // packed structure to allow a single socket write to dump the
 // length and the following answer. The packing attribute is gcc specific.
 struct glommer {
-    int    length;
+    size_t  length;
     #ifdef NS_PACKETSZ
         u_char answer[NS_PACKETSZ*4];   // with a resolver, we return resolver answers
     #else
@@ -150,8 +150,8 @@
 ////////////////////////////////////////////////
 // helper to manipulate recipient counts
 //
-int incr_rcpt_count(char *user);
-int incr_rcpt_count(char *user) {
+int incr_rcpt_count(const char *user);
+int incr_rcpt_count(const char *user) {
     pthread_mutex_lock(&rate_mutex);
         rcpt_rates::iterator i = rcpt_counts.find(user);
         int c = 1;
@@ -172,8 +172,8 @@
 void discard(context_map &cm);
 void discard(context_map &cm) {
     for (context_map::iterator i=cm.begin(); i!=cm.end(); i++) {
-        char *x = (*i).first;
-        free(x);
+        const char *x = (*i).first;
+        free((void*)x);
     }
     cm.clear();
 }
@@ -182,8 +182,8 @@
 ////////////////////////////////////////////////
 // helper to register a string in a context_map
 //
-void register_string(context_map &cm, char *name, CONTEXT *con);
-void register_string(context_map &cm, char *name, CONTEXT *con) {
+void register_string(context_map &cm, const char *name, CONTEXT *con);
+void register_string(context_map &cm, const char *name, CONTEXT *con) {
     context_map::iterator i = cm.find(name);
     if (i != cm.end()) return;
     char *x = strdup(name);
@@ -280,7 +280,7 @@
         bool last = (!pc->reference_count) && (pc != config);
     pthread_mutex_unlock(&config_mutex);
     if (last) delete pc;  // free this config, since we were the last reference to it
-    if (helo) free(helo);
+    if (helo) free((void*)helo);
     reset(true);
 }
 
@@ -290,10 +290,10 @@
         delete dwp;
         delayer.pop_front();
     }
-    if (mailaddr)      free(mailaddr);
-    if (queueid)       free(queueid);
-    if (authenticated) free(authenticated);
-    if (client_name)   free(client_name);
+    if (mailaddr)      free((void*)mailaddr);
+    if (queueid)       free((void*)queueid);
+    if (authenticated) free((void*)authenticated);
+    if (client_name)   free((void*)client_name);
     delayer.clear();
     discard(env_to);
     if (memory)   delete memory;
@@ -423,7 +423,7 @@
     return rs;
 }
 
-void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) {
+void mlfiPriv::need_content_filter(const char *rcpt, CONTEXT &con) {
     register_string(env_to, rcpt, &con);
     if (!memory) {
         // first recipient that needs content filtering sets
@@ -453,7 +453,7 @@
 ////////////////////////////////////////////////
 // syslog a message
 //
-void my_syslog(mlfiPriv *priv, char *text) {
+void my_syslog(mlfiPriv *priv, const char *text) {
     char buf[maxlen];
     if (priv) {
         snprintf(buf, sizeof(buf), "%s: %s", priv->queueid, text);
@@ -473,7 +473,7 @@
     }
 }
 
-void my_syslog(mlfiPriv *priv, string text) {
+void my_syslog(mlfiPriv *priv, const string text) {
     if (debug_syslog > 3) {
         char buf[maxlen];
         strncpy(buf, text.c_str(), sizeof(buf));
@@ -482,7 +482,7 @@
     }
 }
 
-void my_syslog(char *text) {
+void my_syslog(const char *text) {
     my_syslog(NULL, text);
 }
 
@@ -579,8 +579,8 @@
 //  If we cannot get an answer, we just accept the mail.
 //
 //
-int dns_interface(mlfiPriv &priv, char *question, bool maybe_ip, ns_map *nameservers);
-int dns_interface(mlfiPriv &priv, char *question, bool maybe_ip, ns_map *nameservers) {
+int dns_interface(mlfiPriv &priv, const char *question, bool maybe_ip, ns_map *nameservers);
+int dns_interface(mlfiPriv &priv, const char *question, bool maybe_ip, ns_map *nameservers) {
     // tell sendmail we are still working
     #if _FFR_SMFI_PROGRESS
         if (priv.eom) smfi_progress(priv.ctx);
@@ -639,7 +639,7 @@
                             char nam[NS_MAXDNAME+1];
                             char         *n = nam;
                             const u_char *p = ns_rr_rdata(rr);
-                            while (((n-nam) < NS_MAXDNAME) && ((p-glom.answer) < glom.length) && *p) {
+                            while (((n-nam) < NS_MAXDNAME) && ((size_t)(p-glom.answer) < glom.length) && *p) {
                                 size_t s = *(p++);
                                 if (s > 191) {
                                     // compression pointer
@@ -649,8 +649,8 @@
                                     s = *(p++);
                                 }
                                 if (s > 0) {
-                                    if ((n-nam)         >= (NS_MAXDNAME-s)) break;  // destination would overflow name buffer
-                                    if ((p-glom.answer) >= (glom.length-s)) break;  // source outside bounds of answer
+                                    if ((size_t)(n-nam)         >= (NS_MAXDNAME-s)) break;  // destination would overflow name buffer
+                                    if ((size_t)(p-glom.answer) >= (glom.length-s)) break;  // source outside bounds of answer
                                     memcpy(n, p, s);
                                     n += s;
                                     p += s;
@@ -697,8 +697,8 @@
 ////////////////////////////////////////////////
 //  check a single dnsbl
 //
-bool check_single(mlfiPriv &priv, int ip, char *suffix);
-bool check_single(mlfiPriv &priv, int ip, char *suffix) {
+bool check_single(mlfiPriv &priv, int ip, const char *suffix);
+bool check_single(mlfiPriv &priv, int ip, const char *suffix) {
     // make a dns question
     const u_char *src = (const u_char *)&ip;
     if (src[0] == 127) return false;    // don't do dns lookups on localhost
@@ -758,8 +758,8 @@
 //  as a string registered in hosts.
 //  otherwise, return false and preserve the value of found.
 //
-bool uriblookup(mlfiPriv &priv, string_set &hosts, char *hostname, char *top, char *&found) ;
-bool uriblookup(mlfiPriv &priv, string_set &hosts, char *hostname, char *top, char *&found) {
+bool uriblookup(mlfiPriv &priv, string_set &hosts, const char *hostname, const char *top, const char *&found) ;
+bool uriblookup(mlfiPriv &priv, string_set &hosts, const char *hostname, const char *top, const char *&found) {
     // top is pointer to '.' char at end of base domain, or null for ip address form
     // so for hostname of www.fred.mydomain.co.uk
     // top points to-----------------------^
@@ -767,10 +767,8 @@
     char buf[maxlen];
     if (top) {
         // add one more component
-        *top = '\0';
-        char *x = strrchr(hostname, '.');
+        const char *x = (const char *)memrchr(hostname, '.', top-hostname);
         if (x) hostname = x+1;
-        *top = '.';
     }
     snprintf(buf, sizeof(buf), "%s.%s.", hostname, priv.uribl_suffix);
     if (dns_interface(priv, buf, false, NULL)) {
@@ -798,8 +796,8 @@
 //  as a string registered in hosts.
 //  otherwise, return false and preserve the value of found.
 //
-bool check_uribl(mlfiPriv &priv, string_set &hosts, char *hostname, char *&found) ;
-bool check_uribl(mlfiPriv &priv, string_set &hosts, char *hostname, char *&found) {
+bool check_uribl(mlfiPriv &priv, string_set &hosts, const char *hostname, const char *&found) ;
+bool check_uribl(mlfiPriv &priv, string_set &hosts, const char *hostname, const char *&found) {
     in_addr ip;
     if (inet_aton(hostname, &ip)) {
         const u_char *src = (const u_char *)&ip.s_addr;
@@ -813,12 +811,10 @@
         return (uriblookup(priv, hosts, adr, NULL, found));
     }
 
-    char *top, *top2, *top3;
+    const char *top, *top2, *top3;
     top = strrchr(hostname, '.');
     if (top) {
-        *top = '\0';
-        top2 = strrchr(hostname, '.');
-        *top = '.';
+        top2 = (const char *)memrchr(hostname, '.', top-hostname);
 
         if (top2) {
             string_set::iterator i = priv.memory->get_cctlds()->find(top2+1);
@@ -826,12 +822,10 @@
             // if we have a 2-level-cctld, just look at top three levels of the name
             if (i != x) return uriblookup(priv, hosts, hostname, top2, found);
 
-            *top2 = '\0';
-            top3 = strrchr(hostname, '.');
-            *top2 = '.';
+            // if we have more than 3 levels in the name, look at the top three levels of the name
+            top3 = (const char *)memrchr(hostname, '.', top2-hostname);
+            if (top3 && uriblookup(priv, hosts, hostname, top2, found)) return true;
 
-            // if we have more than 3 levels in the name, look at the top three levels of the name
-            if (top3 && uriblookup(priv, hosts, hostname, top2, found)) return true;
             // if that was not found, fall thru to looking at the top two levels
         }
         // look at the top two levels of the name
@@ -845,11 +839,10 @@
 //  check the hosts from the body against the content filter and uribl dnsbls
 //
 //
-bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&msg, char *&host, int &ip, char *&found);
-bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&msg, char *&host, int &ip, char *&found) {
+bool check_hosts(mlfiPriv &priv, bool random, int limit, const char *&msg, const char *&host, int &ip, const char *&found);
+bool check_hosts(mlfiPriv &priv, bool random, int limit, const char *&msg, const char *&host, int &ip, const char *&found) {
     found = NULL;   // normally ip address style
     if (!priv.content_suffix && !priv.uribl_suffix) return false;   // nothing to check
-    CONFIG     &dc     = *priv.pc;
     string_set &hosts  = priv.memory->get_hosts();
     string_set &ignore = *priv.content_host_ignore;
 
@@ -937,7 +930,7 @@
                     msg = priv.content_message;
                     string_map::iterator j = nameservers.ns_host.find(host);
                     if (j != nameservers.ns_host.end()) {
-                        char *refer = (*j).second;
+                        const char *refer = (*j).second;
                         char buf[maxlen];
                         snprintf(buf, sizeof(buf), "%s with nameserver %s", refer, host);
                         host = register_string(hosts, buf);    // put a copy into hosts, and return that reference
@@ -964,8 +957,8 @@
 // to lower case. Some clients enclose the entire address in single quotes,
 // so we strip those as well.
 //
-char *to_lower_string(char *email);
-char *to_lower_string(char *email) {
+const char *to_lower_string(const char *email);
+const char *to_lower_string(const char *email) {
     int n = strlen(email);
     if (email[0] == '<') {
         // assume it also ends with >
@@ -1012,9 +1005,9 @@
 {
     mlfiPriv &priv     = *MLFIPRIV;
     priv.mailaddr      = to_lower_string(from[0]);
-    priv.queueid       = strdup(smfi_getsymval(ctx, "i"));
-    priv.authenticated = smfi_getsymval(ctx, "{auth_authen}");
-    priv.client_name   = smfi_getsymval(ctx, "_");
+    priv.queueid       = strdup(smfi_getsymval(ctx, (char*)"i"));
+    priv.authenticated = smfi_getsymval(ctx, (char*)"{auth_authen}");
+    priv.client_name   = smfi_getsymval(ctx, (char*)"_");
     if (!priv.helo)         priv.helo          = strdup("unknown");
     if (priv.authenticated) priv.authenticated = strdup(priv.authenticated);
     if (priv.client_name)   priv.client_name   = strdup(priv.client_name);
@@ -1032,47 +1025,46 @@
     DNSBLP rejectlist = NULL;   // list that caused the reject
     mlfiPriv &priv = *MLFIPRIV;
     CONFIG &dc = *priv.pc;
-    char  *rcptaddr  = rcpt[0];
-    char  *loto      = to_lower_string(rcptaddr);
+    const char  *rcptaddr  = rcpt[0];
+    const char  *loto      = to_lower_string(rcptaddr);
 
     // some version of sendmail allowed rcpt to:<> and passed it thru to the milters
     if (strcmp(loto, "<>") == 0) {
-        smfi_setreply(ctx, "550", "5.7.1", "bogus recipient");
+        smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"bogus recipient");
         return SMFIS_REJECT;
     }
     // priv.mailaddr sending original message to loto
     CONTEXT     &con = *(dc.find_context(loto)->find_context(priv.mailaddr));
     VERIFYP      ver = con.find_verify(loto);
-    char  *fromvalue = con.find_from(priv.mailaddr, true);
+    const char *fromvalue = con.find_from(priv.mailaddr, true);
     // tell spam assassin and dccifd about this recipient
     if (priv.assassin) priv.assassin->mlfi_envrcpt(ctx, loto);
     if (priv.dccifd)   priv.dccifd->mlfi_envrcpt(ctx, loto, con.get_grey() && !priv.authenticated);
     // loto sending a reply back to priv.mailaddr
     CONTEXT    &con2 = *(dc.find_context(priv.mailaddr)->find_context(loto));
-    char *replyvalue = con2.find_from(loto);
+    const char *replyvalue = con2.find_from(loto);
     if (debug_syslog > 1) {
         char buf[maxlen];
         char msg[maxlen];
         snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s state %s reply state %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen), fromvalue, replyvalue);
         my_syslog(&priv, msg);
     }
-    free(loto);
+    free((void*)loto);
     status st;
     if (replyvalue == token_black) {
-        smfi_setreply(ctx, "550", "5.7.1", "recipient can not reply due to blacklisting");
+        smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"recipient can not reply due to blacklisting");
         return SMFIS_REJECT;
     }
     if (priv.authenticated) {
         int c = incr_rcpt_count(priv.authenticated);
         int l = dc.default_context->find_rate(priv.authenticated);
         if (debug_syslog > 1) {
-            char buf[maxlen];
             char msg[maxlen];
             snprintf(msg, sizeof(msg), "authenticated id %s (%d recipients, %d limit)", priv.authenticated, c, l);
             my_syslog(&priv, msg);
         }
         if (c > l) {
-            smfi_setreply(ctx, "550", "5.7.1", "recipient rate limit exceeded");
+            smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"recipient rate limit exceeded");
             return SMFIS_REJECT;
         }
         st = white;
@@ -1094,31 +1086,31 @@
         inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr));
         char buf[maxlen];
         snprintf(buf, sizeof(buf), rejectlist->message, adr, adr);
-        smfi_setreply(ctx, "550", "5.7.1", buf);
+        smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", buf);
         return SMFIS_REJECT;
     }
     if (st == oksofar) {
-        char *msg = con.generic_match(priv.client_name);
+        const char *msg = con.generic_match(priv.client_name);
         if (msg) {
             // reject the recipient based on generic reverse dns
             char buf[maxlen];
             snprintf(buf, sizeof(buf), msg, priv.client_name);
-            smfi_setreply(ctx, "550", "5.7.1", buf);
+            smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", buf);
             return SMFIS_REJECT;
         }
     }
     if (st == black) {
         // reject the recipient based on blacklisting either from or to
-        smfi_setreply(ctx, "550", "5.7.1", "no such user");
+        smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"no such user");
         return SMFIS_REJECT;
     }
     if (ver) {
         // try to verify this from/to pair of addresses even if it might be explicitly whitelisted
-        char *loto = to_lower_string(rcptaddr);
+        const char *loto = to_lower_string(rcptaddr);
         bool rc = ver->ok(priv.mailaddr, loto);
-        free(loto);
+        free((void*)loto);
         if (!rc) {
-            smfi_setreply(ctx, "550", "5.7.1", "no such user");
+            smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", (char*)"no such user");
             return SMFIS_REJECT;
         }
     }
@@ -1128,7 +1120,7 @@
     WHITELISTERP w = con2.find_autowhite(loto, priv.mailaddr);
     // check if local part is too big
     const int max_local_size = 30;
-    char *p = strchr(loto, '@');
+    const char *p = strchr(loto, '@');
     int len = (p) ? p-loto : max_local_size;
     if (len >= max_local_size) w = NULL;    // too big, pretend we don't have a whitelister
     // record it if we have a whitelister
@@ -1137,7 +1129,7 @@
         priv.delayer.push_back(dwp);
     }
     else {
-        free(loto);
+        free((void*)loto);
     }
 
     // accept the recipient
@@ -1148,7 +1140,7 @@
         if (con.get_content_filtering()) {
             if (!priv.content_context) priv.content_context = &con;
             else if (con.get_require() && (priv.content_context != &con)) {
-                smfi_setreply(ctx, "452", "4.2.1", "incompatible filtering contexts");
+                smfi_setreply(ctx, (char*)"452", (char*)"4.2.1", (char*)"incompatible filtering contexts");
                 return SMFIS_TEMPFAIL;
             }
         }
@@ -1189,7 +1181,7 @@
     while (!priv.delayer.empty()) {
         DELAYWHITEP dwp = priv.delayer.front();
         if (!priv.is_bulk_precedence) {
-            char         *loto = dwp->get_loto();
+            const char   *loto = dwp->get_loto();
             WHITELISTERP w     = dwp->get_w();
             CONTEXTP     con2  = dwp->get_con();
             if (debug_syslog > 1) {
@@ -1226,10 +1218,8 @@
 {
     sfsistat  rc;
     mlfiPriv &priv = *MLFIPRIV;
-    CONFIG   &dc   = *priv.pc;
-    char     *host = NULL;
+    const char *host = NULL;
     int       ip;
-    status    st;
     // process end of message
     priv.eom = true;
     if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE;
@@ -1247,12 +1237,12 @@
         bool random = false;
         int  limit  = 0;
         for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) {
-            char *rcpt   = (*i).first;
+            const char *rcpt   = (*i).first;
             CONTEXT &con = *((*i).second);
             if (!con.acceptable_content(*priv.memory, score, bulk, msg)) {
                 // bad html tags or excessive hosts or
                 // high spam assassin score or dcc bulk threshold exceedeed
-                smfi_delrcpt(ctx, rcpt);
+                smfi_delrcpt(ctx, (char*)rcpt);
             }
             else {
                 alive.insert(rcpt);
@@ -1262,7 +1252,8 @@
         }
         bool rejecting = alive.empty(); // if alive is empty, we must have set msg above in acceptable_content()
         if (!rejecting) {
-            char *fmt, *found;
+            const char *fmt;
+            const char *found;
             if (check_hosts(priv, random, limit, fmt, host, ip, found)) {
                 if (found) {
                     // uribl style
@@ -1281,7 +1272,7 @@
         }
         if (!rejecting) {
             if (priv.want_dccgrey && grey) {
-                smfi_setreply(ctx, "452", "4.2.1", "temporary greylist embargoed");
+                smfi_setreply(ctx, (char*)"452", (char*)"4.2.1", (char*)"temporary greylist embargoed");
                 rc = SMFIS_TEMPFAIL;
             }
             else rc = SMFIS_CONTINUE;
@@ -1289,14 +1280,14 @@
         else if (!priv.have_whites) {
             // can reject the entire message
             snprintf(buf, sizeof(buf), "%s", msg.c_str());
-            smfi_setreply(ctx, "550", "5.7.1", buf);
+            smfi_setreply(ctx, (char*)"550", (char*)"5.7.1", buf);
             rc = SMFIS_REJECT;
         }
         else {
             // need to accept it but remove the recipients that don't want it
             for (string_set::iterator i=alive.begin(); i!=alive.end(); i++) {
-                char *rcpt = *i;
-                smfi_delrcpt(ctx, rcpt);
+                const char *rcpt = *i;
+                smfi_delrcpt(ctx, (char*)rcpt);
             }
             rc = SMFIS_CONTINUE;
         }
@@ -1324,7 +1315,7 @@
 
 struct smfiDesc smfilter =
 {
-    "DNSBL",            // filter name
+    (char*)"DNSBL",     // filter name
     SMFI_VERSION,       // version code -- do not change
     SMFIF_DELRCPT,      // flags
     mlfi_connect,       // connection info filter
@@ -1390,7 +1381,7 @@
         struct stat st;
         bool reload = false;
         for (string_set::iterator i=dc.config_files.begin(); i!=dc.config_files.end(); i++) {
-            char *fn = *i;
+            const char *fn = *i;
             if (stat(fn, &st))           reload = true; // file disappeared
             else if (st.st_mtime > then) reload = true; // file modified
             if (reload) break;
@@ -1419,8 +1410,8 @@
 }
 
 
-void usage(char *prog);
-void usage(char *prog)
+void usage(const char *prog);
+void usage(const char *prog)
 {
     fprintf(stderr, "Usage: %s  [-d [level]] [-c] [-s] [-e from|to] [-b dccifd-addr] -r port -p sm-sock-addr [-t timeout]\n", prog);
     fprintf(stderr, "where dccifd_addr is for the connection to dccifd\n");
@@ -1442,8 +1433,8 @@
 
 
 
-void setup_socket(char *sock);
-void setup_socket(char *sock) {
+void setup_socket(const char *sock);
+void setup_socket(const char *sock) {
     unlink(sock);
 }
 
@@ -1469,7 +1460,7 @@
     bool stress  = false;
     bool setconn = false;
     bool setreso = false;
-    char *email = NULL;
+    const char *email = NULL;
     int c;
     const char *args = "b:r:p:t:e:d:chs";
     extern char *optarg;
@@ -1521,7 +1512,7 @@
                 break;
 
             case 'e':
-                if (email) free(email);
+                if (email) free((void*)email);
                 email = strdup(optarg);
                 break;
 
@@ -1587,7 +1578,7 @@
                 fprintf(stdout, "envelope to   <%s> finds context %s\n", to, con->get_full_name(buf,maxlen));
                 CONTEXTP fc = con->find_context(from);
                 fprintf(stdout, "envelope from <%s> finds context %s\n", from, fc->get_full_name(buf,maxlen));
-                char *st = fc->find_from(from);
+                const char *st = fc->find_from(from);
                 fprintf(stdout, "envelope from <%s> finds status %s\n", from, st);
                 delete conf;
             }
--- a/src/dnsbl.h	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/dnsbl.h	Tue Jun 10 08:58:42 2008 -0700
@@ -32,13 +32,13 @@
 	int 	fd; 							// to talk to dns resolver process
 	bool	err;							// did we get any errors on the resolver socket?
 	int 	ip; 							// ip4 address of the smtp client
-	char	*helo;							// helo from client
+    const char        *helo;                // helo from client
 	map<DNSBLP, bool> checked;				// map of dnsblp to result of (ip listed on that dnsbl)
 	// message specific data
-	char			*mailaddr;				// envelope from value
-	char			*queueid;				// sendmail queue id
-	char			*authenticated; 		// client authenticated? if so, suppress all dnsbl checks, but check rate limits
-	char			*client_name;			// fully qualified host name of the smtp client
+    const char      *mailaddr;              // envelope from value
+    const char      *queueid;               // sendmail queue id
+    const char      *authenticated;         // client authenticated? if so, suppress all dnsbl checks, but check rate limits
+    const char      *client_name;           // fully qualified host name of the smtp client
 	bool			have_whites;			// have at least one whitelisted recipient? need to accept content and remove all non-whitelisted recipients if it fails
 	bool			only_whites;			// every recipient is whitelisted?
 	bool			want_spamassassin;		// at least one non-whitelisted recipient has a non zero spamassassin limit
@@ -50,10 +50,10 @@
 	context_map 	env_to; 				// map each non-whitelisted recipient to their filtering context
 	recorder		*memory;				// memory for the content scanner
 	url_scanner 	*scanner;				// object to handle body scanning
-	char			*content_suffix;		// for url body filtering based on ip addresses of hostnames in the body
-	char			*content_message;		// ""
-	char			*uribl_suffix;			// for uribl body filtering based on hostnames in the body
-	char			*uribl_message; 		// ""
+    const char      *content_suffix;        // for url body filtering based on ip addresses of hostnames in the body
+    const char      *content_message;       // ""
+    const char      *uribl_suffix;          // for uribl body filtering based on hostnames in the body
+    const char      *uribl_message;         // ""
 	string_set		*content_host_ignore;	// ""
 	SpamAssassin	*assassin;
 	DccInterface	*dccifd;
@@ -66,11 +66,11 @@
 	void return_fd();
 	size_t my_read(char *buf, size_t len);
 	size_t my_write(const char *buf, size_t len);
-	void need_content_filter(char *rcpt, CONTEXT &con);
+    void need_content_filter(const char *rcpt, CONTEXT &con);
 };
 
-void my_syslog(mlfiPriv *priv, char *text);
-void my_syslog(mlfiPriv *priv, string text);
-void my_syslog(char *text);
+void my_syslog(mlfiPriv *priv, const char *text);
+void my_syslog(mlfiPriv *priv, const string text);
+void my_syslog(const char *text);
 
 #endif
--- a/src/includes.h	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/includes.h	Tue Jun 10 08:58:42 2008 -0700
@@ -15,6 +15,15 @@
 	#include "config.h"
 #endif
 
+#include <map>
+#include <list>
+#include <set>
+#include <fstream>
+#include <regex.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string>
+
 #include "tokenizer.h"
 #include "context.h"
 #include "dnsbl.h"
--- a/src/scanner.h	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/scanner.h	Tue Jun 10 08:58:42 2008 -0700
@@ -21,8 +21,8 @@
 	string_set	*tlds;		// valid tlds
 	string_set	*cctlds;	// valid cctlds
 	string_set	hosts;
-	int 		bad_html_tags;
-	int 		binary_tags;
+    size_t      bad_html_tags;
+    size_t      binary_tags;
 
 public:
 	recorder(mlfiPriv *priv_, string_set &html_tags_, string_set &tlds_, string_set &cctlds_);
@@ -36,8 +36,8 @@
 	string_set *get_cctlds()					{ return cctlds;																	};
 	string_set *get_tlds()						{ return tlds;																		};
 	string_set &get_hosts() 					{ return hosts; 																	};
-	bool		excessive_bad_tags(int limit)	{ return (limit > 0) && (bad_html_tags > limit) && (bad_html_tags > 3*binary_tags); };
-	bool		excessive_hosts(int limit)		{ return (limit > 0) && (hosts.size() > limit); 									};
+    bool        excessive_bad_tags(size_t limit){ return (limit > 0) && (bad_html_tags > limit) && (bad_html_tags > 3*binary_tags); };
+    bool        excessive_hosts(size_t limit)   { return (limit > 0) && (hosts.size() > limit);                                     };
 
 };
 
--- a/src/spamass.cpp.in	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/spamass.cpp.in	Tue Jun 10 08:58:42 2008 -0700
@@ -19,13 +19,13 @@
 #include <unistd.h>
 
 
-char *spamc = "@SPAMC@";
-char *spamc_empty = "";
+const char *spamc = "@SPAMC@";
+const char *spamc_empty = "";
 static bool warnedmacro = false;    // have we logged that we couldn't fetch a macro?
 const  int  maxlen = 1000;          // used for snprintf buffers
 
 
-SpamAssassin::SpamAssassin(mlfiPriv *priv_, int ip, char *helo_, char *from, char *qid)
+SpamAssassin::SpamAssassin(mlfiPriv *priv_, int ip, const char *helo_, const char *from, const char *qid)
 {
     error           = false;
     running         = false;
@@ -64,7 +64,7 @@
 }
 
 
-void SpamAssassin::mlfi_envrcpt(SMFICTX *ctx, char *envrcpt)
+void SpamAssassin::mlfi_envrcpt(SMFICTX *ctx, const char *envrcpt)
 {
     if (first_recipient) {
         first_recipient = false;
@@ -123,7 +123,7 @@
 }
 
 
-void SpamAssassin::mlfi_header(char* headerf, char* headerv)
+void SpamAssassin::mlfi_header(const char* headerf, const char* headerv)
 {
     if (!running) Connect();
     if (running) {
@@ -144,9 +144,9 @@
 }
 
 
-void SpamAssassin::mlfi_body(u_char *bodyp, size_t bodylen)
+void SpamAssassin::mlfi_body(const u_char *bodyp, size_t bodylen)
 {
-    output((char *)bodyp, bodylen);
+    output((const char *)bodyp, bodylen);
 }
 
 
@@ -200,8 +200,8 @@
 
             // execute spamc
             char* argv[3];
-            argv[0] = spamc;
-            argv[1] = "-c";
+            argv[0] = (char*)spamc;
+            argv[1] = (char*)"-c";
             argv[2] = NULL;
             execvp(argv[0] , argv); // does not return!
             _exit(1);               // exec failed
@@ -241,8 +241,8 @@
     }
 
     // send to SpamAssassin
-    long total = 0;
-    long wsize = 0;
+    size_t total = 0;
+    size_t wsize = 0;
     string reason;
     int status;
     do {
@@ -394,9 +394,9 @@
 }
 
 
-char *SpamAssassin::getorwarnmacro(SMFICTX *ctx, char *macro, char *def, char *scope)
+const char *SpamAssassin::getorwarnmacro(SMFICTX *ctx, const char *macro, const char *def, const char *scope)
 {
-    char *rc = smfi_getsymval(ctx, macro);
+    const char *rc = smfi_getsymval(ctx, (char*)macro);
     if (!rc) {
         rc = def;
         warnmacro(macro, scope);
@@ -405,7 +405,7 @@
 }
 
 
-void SpamAssassin::warnmacro(char *macro, char *scope)
+void SpamAssassin::warnmacro(const char *macro, const char *scope)
 {
     if (warnedmacro) return;
     char buf[maxlen];
--- a/src/spamass.h	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/spamass.h	Tue Jun 10 08:58:42 2008 -0700
@@ -21,21 +21,21 @@
 
 #include <list>
 
-extern char *spamc;
-extern char *spamc_empty;
+extern const char *spamc;
+extern const char *spamc_empty;
 using namespace std;
 
 class mlfiPriv;
 
 class SpamAssassin {
 public:
-	SpamAssassin(mlfiPriv *priv_, int ip, char *helo_, char *from, char *qid);
+    SpamAssassin(mlfiPriv *priv_, int ip, const char *helo_, const char *from, const char *qid);
 	~SpamAssassin();
 
-	void mlfi_envrcpt(SMFICTX *ctx, char *envrcpt);
-	void mlfi_header(char* headerf, char* headerv);
+    void mlfi_envrcpt(SMFICTX *ctx, const char *envrcpt);
+    void mlfi_header(const char* headerf, const char* headerv);
 	void mlfi_eoh();
-	void mlfi_body(u_char *bodyp, size_t bodylen);
+    void mlfi_body(const u_char *bodyp, size_t bodylen);
 	int  mlfi_eom();
 
 private:
@@ -48,8 +48,8 @@
 	int  read_pipe();
 	void empty_and_close_pipe();
 	void closeall(int fd);
-	char *getorwarnmacro(SMFICTX *ctx, char *macro, char *def, char *scope);
-	void warnmacro(char *macro, char *scope);
+    const char *getorwarnmacro(SMFICTX *ctx, const char *macro, const char *def, const char *scope);
+    void warnmacro(const char *macro, const char *scope);
 
 public:
 	bool error; 			// spamc died or cannot work
@@ -61,9 +61,9 @@
 	int 	 ip4;		// ip4 address of smtp client
 
 	// strings owned by main dnsbl
-	char *helo; 		// client helo value
-	char *envfrom;		// envelope from value for this message
-	char *queueid;		// the sendmail queue id for this message
+    const char *helo;       // client helo value
+    const char *envfrom;    // envelope from value for this message
+    const char *queueid;    // the sendmail queue id for this message
 
 	// Process handling variables
 	pid_t pid;
--- a/src/tokenizer.cpp	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/tokenizer.cpp	Tue Jun 10 08:58:42 2008 -0700
@@ -287,7 +287,7 @@
 };
 
 
-TOKEN::TOKEN(char *fn, string_set *includes) {
+TOKEN::TOKEN(const char *fn, string_set *includes) {
 	pushed = false;
 	include_files = includes;
 	include(fn);
@@ -301,7 +301,7 @@
 
 void TOKEN::pop() {
 	ifstream *is = streams.front();
-	char *fn = filenames.front();
+    const char *fn = filenames.front();
 	streams.pop_front();
 	filenamess.erase(fn);
 	if (filenames.size() > 1)	filenames.pop_front();
@@ -339,7 +339,7 @@
 }
 
 
-bool TOKEN::include(char *fn) {
+bool TOKEN::include(const char *fn) {
 	string_set::iterator i = filenamess.find(fn);
 	if (i != filenamess.end()) {
 		token_error("redundant or recursive include file detected");
@@ -363,9 +363,9 @@
 }
 
 
-char *TOKEN::next() {
+const char *TOKEN::next() {
 	if (!pending_tokens.empty()) {
-		char *t = pending_tokens.front();
+        const char *t = pending_tokens.front();
 		pending_tokens.pop_front();
 		return t;
 	}
@@ -445,10 +445,10 @@
 
 	buffer[count] = '\0';
 	if (count == 0) return NULL;
-	char *t = register_string((char*)buffer);
+    const char *t = register_string((char*)buffer);
 	if (t == token_include) {
-		char *f = next();	// should be file name
-		char *s = next();	// should be semicolon
+        const char *f = next();   // should be file name
+        const char *s = next();   // should be semicolon
 		if (s == token_semi) {
 			include(f);
 			return next();
@@ -464,7 +464,7 @@
 
 
 int TOKEN::nextint() {
-	char *t = next();
+    const char *t = next();
 	char *e;
 	long i = strtol(t, &e, 10);
 	if (*e != '\0') {
@@ -516,10 +516,10 @@
 void TOKEN::token_error() {
 	token_error("syntax error at line %d in file %s -- ", cur_line(), cur_fn());
 	line_list::iterator   j = linenumbers.begin();
-	string_list::iterator i = filenames.begin();
+    string_list::const_iterator i = filenames.begin();
 	for (; i!=filenames.end(); i++,j++) {
 		if (i != filenames.begin()) {
-			char *fn = (*i);
+            const char *fn = (*i);
 			int   li = (*j);
 			token_error("    included from line %d in file %s -- ", li, fn);
 		}
--- a/src/tokenizer.h	Wed Apr 30 13:11:32 2008 -0700
+++ b/src/tokenizer.h	Tue Jun 10 08:58:42 2008 -0700
@@ -6,27 +6,17 @@
 
 */
 
-#ifndef tokenizer_include
-#define tokenizer_include
-
-#include <fstream>
-#include <list>
-#include <set>
-#include <stdio.h>
-#include <ctype.h>
-
-
 using namespace std;
 
 struct ltstr {
-    bool operator()(char* s1, char* s2) const {
+    bool operator()(const char* s1, const char* s2) const {
         return strcmp(s1, s2) < 0;
     }
 };
 
 typedef list<ifstream *>    stream_list;
-typedef list<char *>        string_list;
-typedef set<char *, ltstr>  string_set;
+typedef list<const char *>          string_list;
+typedef set<const char *, ltstr>    string_set;
 typedef list<int>           line_list;
 
 class TOKEN {
@@ -44,13 +34,13 @@
     void push_char(u_char c);
 
 public:
-    TOKEN(char *fn, string_set *includes);
+    TOKEN(const char *fn, string_set *includes);
     ~TOKEN();
-    bool        include(char *fn);
-    char        *next();            // return next token
+    bool        include(const char *fn);
+    const char  *next();            // return next token
     int         nextint();
     void        skipeol();          // skip to eol
-    void        push(char *token)   {pending_tokens.push_front(token);};
+    void        push(const char *token) {pending_tokens.push_front(token);};
     const char  *cur_fn()           {return filenames.empty()   ? "" : filenames.front();};
     int         cur_line()          {return linenumbers.empty() ? 0  : linenumbers.front();};
     void        token_error(const char *err);
@@ -60,4 +50,3 @@
     void        token_error();
 };
 
-#endif
--- a/xml/dnsbl.in	Wed Apr 30 13:11:32 2008 -0700
+++ b/xml/dnsbl.in	Tue Jun 10 08:58:42 2008 -0700
@@ -19,7 +19,7 @@
 
     <refentry id="@PACKAGE@.1">
         <refentryinfo>
-            <date>2008-02-02</date>
+            <date>2008-06-08</date>
         </refentryinfo>
 
         <refmeta>
@@ -586,7 +586,7 @@
 
     <refentry id="@PACKAGE@.conf.5">
         <refentryinfo>
-            <date>2008-02-02</date>
+            <date>2008-06-08</date>
         </refentryinfo>
 
         <refmeta>