- Bumped version to 0.3.5
authorMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 10 Jul 2012 05:07:50 +0000 (05:07 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 10 Jul 2012 05:07:50 +0000 (05:07 +0000)
- Added new mmmail SQL schema column "list" in the box table to allow
  to specify that a mailbox is for use as a mailing list and that mailing
  list headers should be added to allow "reply to mailing list" mail client
  features.
- Add feature to mmsmtpd to append mailing-list headers to incomming message
  headers.
- ANSI-fied booleans

mmsoftware/mmmail/scripts/pgsql-tables.sql
mmsoftware/mmmail/scripts/upgrade-0.3.5.sql [new file with mode: 0644]
mmsoftware/mmmail/src/mmpop3d/mmpop3d.c
mmsoftware/mmmail/src/mmpop3d/mmpop3d.h
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.c
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.h

index fab5ac0..3f916d8 100644 (file)
@@ -1,4 +1,4 @@
---- $Id: pgsql-tables.sql,v 1.8 2007/04/03 10:15:57 mmondor Exp $
+--- $Id: pgsql-tables.sql,v 1.9 2012/07/10 05:07:46 mmondor Exp $
 
 BEGIN;
 
@@ -97,6 +97,8 @@ CREATE TABLE "box" (
                                        DEFAULT 'f',
        filter_type     boolean         NOT NULL
                                        DEFAULT 'f',
+       list            boolean         NOT NULL
+                                       DEFAULT 'f',
        description     varchar(64),
        PRIMARY KEY (address)
 );
diff --git a/mmsoftware/mmmail/scripts/upgrade-0.3.5.sql b/mmsoftware/mmmail/scripts/upgrade-0.3.5.sql
new file mode 100644 (file)
index 0000000..07c9a75
--- /dev/null
@@ -0,0 +1,7 @@
+# $Id: upgrade-0.3.5.sql,v 1.1 2012/07/10 05:07:46 mmondor Exp $
+#
+# You should execute this script if you are upgrading mmmail from 0.3.4 or
+# older to 0.3.5 or later, to add the "filter" column to the "box" table.
+#
+
+ALTER TABLE "box" ADD COLUMN "list" boolean NOT NULL DEFAULT FALSE;
index 21b2f86..0e28eb6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmpop3d.c,v 1.61 2010/04/21 22:06:55 mmondor Exp $ */
+/* $Id: mmpop3d.c,v 1.62 2012/07/10 05:07:48 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2008, Matthew Mondor
@@ -87,7 +87,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2001-2007\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmpop3d.c,v 1.61 2010/04/21 22:06:55 mmondor Exp $");
+MMRCSID("$Id: mmpop3d.c,v 1.62 2012/07/10 05:07:48 mmondor Exp $");
 
 
 
@@ -156,8 +156,8 @@ static int (*state_main[])(clientenv *) = {
 
 /* And here are our states */
 static const struct state states[] = {
-    {state_auth, FALSE, "Authenticate first"},
-    {state_main, FALSE, "Already authenticated"}
+    {state_auth, false, "Authenticate first"},
+    {state_main, false, "Already authenticated"}
 };
 
 /* Used for mmsyslog() */
@@ -289,10 +289,10 @@ main(int argc, char **argv)
     CONF.BANDWIDTH_OUT = 12;
     CONF.GBANDWIDTH_IN = 0;
     CONF.GBANDWIDTH_OUT = 0;
-    CONF.RESOLVE_HOSTS = FALSE;
-    CONF.DELAY_ON_ERROR = FALSE;
-    CONF.STATFAIL_LOGIN = FALSE;
-    CONF.STATFAIL_PASSWORD = FALSE;
+    CONF.RESOLVE_HOSTS = false;
+    CONF.DELAY_ON_ERROR = false;
+    CONF.STATFAIL_LOGIN = false;
+    CONF.STATFAIL_PASSWORD = false;
 
     /* Advertize */
     printf("\r\n+++ %s (%s)\r\n\r\n", DAEMON_NAME, DAEMON_VERSION);
@@ -361,11 +361,11 @@ main(int argc, char **argv)
     {
        mmstat_t vstat;
 
-       mmstat_init(&vstat, TRUE, TRUE);
-       mmstat_transact(&vstat, TRUE);
+       mmstat_init(&vstat, true, true);
+       mmstat_transact(&vstat, true);
        mmstat(&vstat, STAT_DELETE, 0, "mmpop3d|current|connections");
        mmstat(&vstat, STAT_DELETE, 0, "mmpop3d|who|*");
-       mmstat_transact(&vstat, FALSE);
+       mmstat_transact(&vstat, false);
     }
 
     make_daemon(CONF.PID_PATH, CONF.CHROOT_DIR);
@@ -411,7 +411,7 @@ main(int argc, char **argv)
     if (strlist)
        mmstrexit();
     if (HASHTABLE_VALID(&command_table))
-       hashtable_destroy(&command_table, FALSE);
+       hashtable_destroy(&command_table, false);
     if (POOL_VALID(&command_pool))
        pool_destroy(&command_pool);
     if (POOL_VALID(&mutexes_pool))
@@ -431,7 +431,7 @@ main(int argc, char **argv)
 static int
 all_noop(clientenv *clenv)
 {
-    reply(clenv, TRUE, "Nothing performed");
+    reply(clenv, true, "Nothing performed");
 
     return (STATE_CURRENT);
 }
@@ -444,13 +444,13 @@ all_quit(clientenv *clenv)
 
     if (clenv->login) {
        if (!do_update(clenv)) {
-           reply(clenv, FALSE, "Error applying changes");
+           reply(clenv, false, "Error applying changes");
            nextstate = STATE_ERROR;
        } else
-           reply(clenv, TRUE, "%s closing connection",
+           reply(clenv, true, "%s closing connection",
                    clenv->iface->hostname);
     } else
-       reply(clenv, TRUE, "%s closing connection",
+       reply(clenv, true, "%s closing connection",
                clenv->iface->hostname);
 
     return (nextstate);
@@ -460,7 +460,7 @@ all_quit(clientenv *clenv)
 static int
 all_beer(clientenv *clenv)
 {
-    reply(clenv, TRUE, "Here, enjoy!");
+    reply(clenv, true, "Here, enjoy!");
 
     return (STATE_CURRENT);
 }
@@ -473,7 +473,7 @@ auth_user(clientenv *clenv)
     char *cmdline = clenv->buffer, *args[3], addr[64], *tmp;
 
     if (clenv->mailbox != NULL)
-       reply(clenv, FALSE, "Username already specified");
+       reply(clenv, false, "Username already specified");
     else {
        if ((mm_straspl(args, cmdline, 2)) == 2) {
            /* Convert first . to @ in username */
@@ -489,11 +489,11 @@ auth_user(clientenv *clenv)
                else
                    mmstat(&clenv->vstat, STAT_UPDATE, 1, "mmpop3d|who|%s",
                            clenv->mailbox);
-               reply(clenv, TRUE, "Username accepted");
+               reply(clenv, true, "Username accepted");
            } else
-               reply(clenv, FALSE, "Invalid username");
+               reply(clenv, false, "Invalid username");
        } else
-           reply(clenv, FALSE, "Command syntax error");
+           reply(clenv, false, "Command syntax error");
     }
 
     return (nextstate);
@@ -535,7 +535,7 @@ auth_pass(clientenv *clenv)
                    mmstat(&clenv->pstat, STAT_UPDATE, 1,
                            "mmpop3d|failed|login|%s", clenv->c_ipaddr);
                nextstate = STATE_END;
-               reply(clenv, FALSE, "Authentication failure");
+               reply(clenv, false, "Authentication failure");
            } else if (checkpw(clenv, args[1], pwhash)) {
                char *domptr;
 
@@ -551,15 +551,15 @@ auth_pass(clientenv *clenv)
                    PQclear(pgres);
                else
                    syslog(LOG_NOTICE, "auth_pass() - PQexecParams(2)");
-               clenv->login = TRUE;
+               clenv->login = true;
                if (!do_buildindex(clenv)) {
-                   reply(clenv, FALSE, "Error");
+                   reply(clenv, false, "Error");
                    nextstate = STATE_ERROR;
                }
                mmsyslog(1, LOGLEVEL,
                        "%08lX Successful login for %s", clenv->id,
                        clenv->mailbox);
-               mmstat_transact(&clenv->pstat, TRUE);
+               mmstat_transact(&clenv->pstat, true);
                mmstat(&clenv->pstat, STAT_UPDATE, 1, "mmpop3d|total|logins");
                mmstat(&clenv->pstat, STAT_UPDATE, 1, "mmmail|box|%s|logins",
                        clenv->mailbox);
@@ -567,14 +567,14 @@ auth_pass(clientenv *clenv)
                domptr++;
                mmstat(&clenv->pstat, STAT_UPDATE, 1,
                        "mmmail|domain|%s|logins", domptr);
-               mmstat_transact(&clenv->pstat, FALSE);
-               reply(clenv, TRUE, "Authentication successful");
+               mmstat_transact(&clenv->pstat, false);
+               reply(clenv, true, "Authentication successful");
                nextstate = STATE_MAIN;
            } else {
                /* User exists but the password was wrong */
                mmsyslog(0, LOGLEVEL, "%08lX Failed login for %s (existing)",
                        clenv->id, clenv->mailbox);
-               mmstat_transact(&clenv->pstat, TRUE);
+               mmstat_transact(&clenv->pstat, true);
                if (CONF.STATFAIL_LOGIN)
                    mmstat(&clenv->pstat, STAT_UPDATE, 1,
                            "mmpop3d|failed|login|%s", clenv->c_ipaddr);
@@ -582,14 +582,14 @@ auth_pass(clientenv *clenv)
                    mmstat(&clenv->pstat, STAT_UPDATE, 1,
                            "mmpop3d|failed|password|%s|%s",
                            clenv->mailbox, clenv->c_ipaddr);
-               mmstat_transact(&clenv->pstat, FALSE);
+               mmstat_transact(&clenv->pstat, false);
                nextstate = STATE_END;
-               reply(clenv, FALSE, "Authentication failure");
+               reply(clenv, false, "Authentication failure");
            }
        } else
-           reply(clenv, FALSE, "Command syntax error");
+           reply(clenv, false, "Command syntax error");
     } else
-       reply(clenv, FALSE, "Specify username first");
+       reply(clenv, false, "Specify username first");
 
     return (nextstate);
 }
@@ -603,7 +603,7 @@ main_rset(clientenv *clenv)
     if (!init_clientenv(clenv))
        nextstate = STATE_ERROR;
     else
-       reply(clenv, TRUE, "Reset state");
+       reply(clenv, true, "Reset state");
 
     return (nextstate);
 }
@@ -612,7 +612,7 @@ main_rset(clientenv *clenv)
 static int
 main_stat(clientenv *clenv)
 {
-    reply(clenv, TRUE, "%ld %ld", clenv->newmessages, clenv->newsize);
+    reply(clenv, true, "%ld %ld", clenv->newmessages, clenv->newsize);
 
     return (STATE_CURRENT);
 }
@@ -631,13 +631,13 @@ main_list(clientenv *clenv)
        i--;                    /* Array starts at 0, not 1 */
        if (i < 0 || i > clenv->messages - 1 || clenv->index == NULL ||
                clenv->index[i].deleted) {
-           reply(clenv, FALSE, "Out of range");
+           reply(clenv, false, "Out of range");
            REGISTER_ERROR(clenv);
        } else
-           reply(clenv, TRUE, "%ld %ld", i + 1, clenv->index[i].size);
+           reply(clenv, true, "%ld %ld", i + 1, clenv->index[i].size);
     } else {
        /* All messages */
-       reply(clenv, TRUE, "%ld message(s) (%ld octets)",
+       reply(clenv, true, "%ld message(s) (%ld octets)",
                clenv->newmessages, clenv->newsize);
        if (clenv->index != NULL) {
            for (i = 0; i < clenv->messages; i++) {
@@ -672,12 +672,12 @@ main_retr(clientenv *clenv)
        i--;                    /* Array starts at 0, not 1 */
        if (i < 0 || !(i < clenv->messages) || clenv->index == NULL ||
                clenv->index[i].deleted) {
-           reply(clenv, FALSE, "Out of range");
+           reply(clenv, false, "Out of range");
            REGISTER_ERROR(clenv);
        } else {
            /* Valid message number to retreive */
            if (clenv->index[i].retreived) {
-               reply(clenv, FALSE, "Already retreived");
+               reply(clenv, false, "Already retreived");
                REGISTER_ERROR(clenv);
            } else {
                clenv->last = i + 1;
@@ -687,7 +687,7 @@ main_retr(clientenv *clenv)
            }
        }
     } else {
-       reply(clenv, FALSE, "Command syntax error");
+       reply(clenv, false, "Command syntax error");
        REGISTER_ERROR(clenv);
     }
 
@@ -706,26 +706,26 @@ main_dele(clientenv *clenv)
            i = atol(args[1]);
            i--;                /* Array starts at 0, not 1 */
            if (i < 0 || !(i < clenv->messages)) {
-               reply(clenv, FALSE, "Out of range");
+               reply(clenv, false, "Out of range");
                REGISTER_ERROR(clenv);
            } else {
                if (!clenv->index[i].deleted) {
-                   clenv->index[i].deleted = TRUE;
+                   clenv->index[i].deleted = true;
                    clenv->newmessages--;
                    clenv->newsize -= clenv->index[i].size;
-                   reply(clenv, TRUE, "Maked to delete");
+                   reply(clenv, true, "Maked to delete");
                    clenv->deleted++;
                } else {
-                   reply(clenv, FALSE, "Already marked to delete");
+                   reply(clenv, false, "Already marked to delete");
                    REGISTER_ERROR(clenv);
                }
            }
        } else {
-           reply(clenv, FALSE, "No messages");
+           reply(clenv, false, "No messages");
            REGISTER_ERROR(clenv);
        }
     } else {
-       reply(clenv, FALSE, "Command syntax error");
+       reply(clenv, false, "Command syntax error");
        REGISTER_ERROR(clenv);
     }
 
@@ -736,7 +736,7 @@ main_dele(clientenv *clenv)
 static int
 main_last(clientenv *clenv)
 {
-    reply(clenv, TRUE, "%ld", clenv->last);
+    reply(clenv, true, "%ld", clenv->last);
 
     return (STATE_CURRENT);
 }
@@ -755,12 +755,12 @@ main_top(clientenv *clenv)
        i1--;                   /* Array starts at 0, not 1 */
        if ((i1 < 0) || !(i1 < clenv->messages) || clenv->index == NULL ||
                clenv->index[i1].deleted) {
-           reply(clenv, FALSE, "Out of range");
+           reply(clenv, false, "Out of range");
            REGISTER_ERROR(clenv);
        } else {
            /* Valid message number to retreive */
            if (clenv->index[i1].retreived) {
-               reply(clenv, FALSE, "Already retreived");
+               reply(clenv, false, "Already retreived");
                REGISTER_ERROR(clenv);
            } else {
                clenv->last = i1 + 1;
@@ -769,7 +769,7 @@ main_top(clientenv *clenv)
            }
        }
     } else {
-       reply(clenv, FALSE, "Command syntax error");
+       reply(clenv, false, "Command syntax error");
        REGISTER_ERROR(clenv);
     }
 
@@ -790,13 +790,13 @@ main_uidl(clientenv *clenv)
        i--;                    /* Array starts at 0, not 1 */
        if (i < 0 || i > clenv->messages - 1 || clenv->index == NULL ||
                clenv->index[i].deleted) {
-           reply(clenv, FALSE, "Out of range");
+           reply(clenv, false, "Out of range");
            REGISTER_ERROR(clenv);
        } else
-           reply(clenv, TRUE, "%ld %s", i + 1, clenv->index[i].id);
+           reply(clenv, true, "%ld %s", i + 1, clenv->index[i].id);
     } else {
        /* All messages */
-       reply(clenv, TRUE, "%ld message(s) (%ld octets)",
+       reply(clenv, true, "%ld message(s) (%ld octets)",
                clenv->newmessages,
                clenv->newsize);
        if (clenv->index != NULL) {
@@ -833,7 +833,7 @@ main_head(clientenv *clenv)
        i--;                    /* Array starts at 0, not 1 */
        if (i < 0 || i > clenv->messages - 1 || clenv->index == NULL ||
                clenv->index[i].deleted) {
-           reply(clenv, FALSE, "Out of range");
+           reply(clenv, false, "Out of range");
            REGISTER_ERROR(clenv);
            return nextstate;
        }
@@ -842,7 +842,7 @@ main_head(clientenv *clenv)
        t = clenv->messages;
 
     /* All messages */
-    reply(clenv, TRUE, "%ld message(s) (%ld octets)", clenv->newmessages,
+    reply(clenv, true, "%ld message(s) (%ld octets)", clenv->newmessages,
            clenv->newsize);
     if (clenv->index != NULL) {
        for (i = 0; i < t; i++) {
@@ -883,12 +883,12 @@ main_page(clientenv *clenv)
        if (i1 < 0 || i2 < 1 || i3 < 1 || i3 > 60 ||
                !(i1 < clenv->messages) || clenv->index == NULL ||
                clenv->index[i1].deleted) {
-           reply(clenv, FALSE, "Out of range");
+           reply(clenv, false, "Out of range");
            REGISTER_ERROR(clenv);
        } else {
            /* Valid message number to retreive */
            if (clenv->index[i1].retreived) {
-               reply(clenv, FALSE, "Already retreived");
+               reply(clenv, false, "Already retreived");
                REGISTER_ERROR(clenv);
            } else {
                clenv->last = i1 + 1;
@@ -897,7 +897,7 @@ main_page(clientenv *clenv)
            }
        }
     } else {
-       reply(clenv, FALSE, "Command syntax error");
+       reply(clenv, false, "Command syntax error");
        REGISTER_ERROR(clenv);
     }
 
@@ -908,7 +908,7 @@ main_page(clientenv *clenv)
 
 
 /* Function used to return standard RFC result strings to the client,
- * and returns FALSE on error.
+ * and returns false on error.
  * NOTE: As we are no longer calling write() directly, but fdbprintf()
  * buffering function instead, it is no longer necessary to check the reply()
  * return value each time it is called. We made sure to ignore SIGPIPE,
@@ -921,7 +921,7 @@ reply(clientenv *clenv, bool result, const char *fmt, ...)
     char buf[1024], *ok = "+OK", *err = "-ERR", *res = ok;
     fdbuf *fdb = clenv->fdb;
     va_list arg_ptr;
-    bool ret = FALSE;
+    bool ret = false;
 
     if (!result)
        res = err;
@@ -931,7 +931,7 @@ reply(clientenv *clenv, bool result, const char *fmt, ...)
     vsnprintf(buf, 1023, fmt, arg_ptr);
     va_end(arg_ptr);
 
-    if (fdbprintf(fdb, "%s %s\r\n", res, buf)) ret = TRUE;
+    if (fdbprintf(fdb, "%s %s\r\n", res, buf)) ret = true;
 
     mmsyslog(3, LOGLEVEL, "%08lX > %s (%s)", clenv->id, res, buf);
 
@@ -944,10 +944,10 @@ clenv_constructor(pnode_t *pn)
 {
        clientenv       *clenv = (clientenv *)pn;
 
-       mmstat_init(&clenv->vstat, TRUE, TRUE);
-       mmstat_init(&clenv->pstat, TRUE, FALSE);
+       mmstat_init(&clenv->vstat, true, true);
+       mmstat_init(&clenv->pstat, true, false);
 
-       return TRUE;
+       return true;
 }
 
 /* ARGSUSED */
@@ -988,7 +988,7 @@ alloc_clientenv(void)
     clientenv *clenv;
 
     pthread_mutex_lock(&clenv_lock);
-    clenv = (clientenv *)pool_alloc(&clenv_pool, FALSE);
+    clenv = (clientenv *)pool_alloc(&clenv_pool, false);
     pthread_mutex_unlock(&clenv_lock);
 
     return (clenv);
@@ -996,7 +996,7 @@ alloc_clientenv(void)
 
 
 /* Useful on RSET to reset initial clenv state,
- * returns TRUE on success or FALSE on error
+ * returns true on success or false on error
  */
 static bool
 init_clientenv(clientenv *clenv)
@@ -1009,8 +1009,8 @@ init_clientenv(clientenv *clenv)
        if ((mnode = clenv->index) != NULL) {
            /* Init message index flags to unread/undeleted */
            for (i = 0, t = clenv->messages; i < t; i++) {
-               mnode[i].deleted = FALSE;
-               mnode[i].retreived = FALSE;
+               mnode[i].deleted = false;
+               mnode[i].retreived = false;
            }
            clenv->last = 1;
        } else
@@ -1020,10 +1020,10 @@ init_clientenv(clientenv *clenv)
        clenv->newsize = clenv->size;
        clenv->retreived = clenv->deleted = 0;
 
-       return (TRUE);
+       return (true);
     }
 
-    return (FALSE);
+    return (false);
 }
 
 
@@ -1071,32 +1071,32 @@ hash_commands(struct command *cmd, size_t min)
     int i;
 
     /* We do not care for any unfreed resources, the program will free them
-     * and exit if we return FALSE.
+     * and exit if we return false.
      */
     if (!pool_init(&command_pool, "command_pool", malloc, free, NULL, NULL,
                sizeof(struct commandnode), 64, 1, 0) ||
            !hashtable_init(&command_table, "commands_table", 64, 1, malloc,
-                   free, commandnode_keycmp, commandnode_keyhash, TRUE))
-       return FALSE;
+                   free, commandnode_keycmp, commandnode_keyhash, true))
+       return false;
 
     for (i = 0; cmd->name != NULL; cmd++, i++) {
        struct commandnode *nod;
  
-       if ((nod = (struct commandnode *)pool_alloc(&command_pool, FALSE))
+       if ((nod = (struct commandnode *)pool_alloc(&command_pool, false))
                == NULL)
-           return FALSE;
+           return false;
        if ((nod->hash = mm_strpack32(cmd->name, min)) == 0)
-           return FALSE;
+           return false;
        nod->command = cmd;
        nod->index = i;
        if (!hashtable_link(&command_table, (hashnode_t *)nod, &nod->hash,
-                   sizeof(uint32_t), TRUE)) {
+                   sizeof(uint32_t), true)) {
            DEBUG_PRINTF("hash_commands", "hashtable_link(%s)", cmd->name);
-           return FALSE;
+           return false;
        }
     }
 
-    return TRUE;
+    return true;
 }
 
 
@@ -1134,22 +1134,22 @@ valid_address(char *to, char *addr)
     /* First locate required @ */
     for (ptr = addr; *ptr != '\0' && *ptr != '@'; ptr++) ;
     if (*ptr == '\0')
-       return (FALSE);
+       return (false);
 
     /* Then scan to the left */
     for (ptr2 = (ptr - 1); ptr2 >= addr && valid_char(*ptr2); ptr2--) ;
     if (ptr2 == (ptr - 1))
-       return (FALSE);
+       return (false);
     ptr2++;
 
     /* Now validate hostname part */
     ptr++;
     if (valid_host(ptr)) {
        mm_strncpy(to, ptr2, 63);
-       return (TRUE);
+       return (true);
     }
 
-    return (FALSE);
+    return (false);
 }
 
 
@@ -1168,7 +1168,7 @@ valid_host(char *host)
        }
     }
     if (ptr == host)
-       return (FALSE);
+       return (false);
 
     /* Now verify that all parts of the hostname are starting with
      * an alphanumeric char
@@ -1176,7 +1176,7 @@ valid_host(char *host)
     ptr = host;
     while (*ptr != '\0') {
        if (!isalnum((int)*ptr) || *ptr == ' ')
-           return (FALSE);
+           return (false);
        else {
            /* Find next host part */
            while (*ptr != '\0' && *ptr != '.')
@@ -1191,7 +1191,7 @@ valid_host(char *host)
        ptr++;
     }
 
-    return (TRUE);
+    return (true);
 }
 
 
@@ -1210,7 +1210,7 @@ valid_char(char c)
 static bool
 do_buildindex(clientenv *clenv)
 {
-    bool       ok = FALSE;
+    bool       ok = false;
     msgnode    *mnode;
     PGresult   *pgres;
     int                rows, i;
@@ -1226,7 +1226,7 @@ do_buildindex(clientenv *clenv)
        rows = PQntuples(pgres);
        /* Allocate array and fill it */
        if ((mnode = (msgnode *)malloc(rows * sizeof(msgnode))) != NULL) {
-           ok = TRUE;
+           ok = true;
            clenv->size = 0;
            for (i = 0; i < rows; i++) {
                mm_strncpy(mnode[i].id, PQgetvalue(pgres, i, 0), 23);
@@ -1241,16 +1241,16 @@ do_buildindex(clientenv *clenv)
                                  63);
 
                c = *(PQgetvalue(pgres, i, 6));
-               mnode[i].read = (c == 't' ? TRUE : FALSE);
+               mnode[i].read = (c == 't' ? true : false);
 
                clenv->size += mnode[i].size;
-               mnode[i].deleted = mnode[i].retreived = FALSE;
+               mnode[i].deleted = mnode[i].retreived = false;
            }
            clenv->index = mnode;
            clenv->messages = clenv->newmessages = rows;
            clenv->newsize = clenv->size;
        } else
-               ok = FALSE;
+               ok = false;
        PQclear(pgres);
     }
 
@@ -1279,7 +1279,7 @@ do_message_load(msgdata *mdata, msgnode *mnode)
                mdata->body = mdata->internal;
                (void) close(fd);
 
-               return TRUE;
+               return true;
            } else
                DEBUG_PRINTF("do_message_load", "mmap() == %s",
                        strerror(errno));
@@ -1294,7 +1294,7 @@ do_message_load(msgdata *mdata, msgnode *mnode)
     mdata->body = NULL;
     mdata->size = 0;
 
-    return FALSE;
+    return false;
 }
 
 /* Frees a previously loaded message body. */
@@ -1314,21 +1314,21 @@ static bool
 do_retreive(clientenv *clenv, msgnode *mnode)
 {
     fdbuf *fdb = clenv->fdb;
-    bool ok = FALSE;
+    bool ok = false;
     msgdata mdata;
 
     if (do_message_load(&mdata, mnode)) {
-       if (reply(clenv, TRUE, "%u octets", (unsigned int)mdata.size)) {
+       if (reply(clenv, true, "%u octets", (unsigned int)mdata.size)) {
            fdbflushw(fdb);
            if (msgwrite(fdb, mdata.body, mdata.size)) {
                if ((fdbwrite(fdb, "\r\n.\r\n", 5)) == 5) {
-                   mnode->retreived = TRUE;
-                   ok = TRUE;
+                   mnode->retreived = true;
+                   ok = true;
                }
            }
            if (!ok) {
                if ((fdbwrite(fdb, "\r\n.\r\n", 5)) == 5)
-                   ok = TRUE;
+                   ok = true;
            }
        }
        do_message_free(&mdata);
@@ -1344,12 +1344,12 @@ do_top(clientenv *clenv, msgnode *mnode, long lines)
 {
     fdbuf *fdb = clenv->fdb;
     register char *tmp, *to;
-    bool ok = FALSE;
+    bool ok = false;
     long i;
     msgdata mdata;
 
     if (do_message_load(&mdata, mnode)) {
-       if (reply(clenv, TRUE,
+       if (reply(clenv, true,
                    "%lu octets, also try PAGE <msg> <page> "
                    "<linesperpage>", mdata.size)) {
            /* First display all message headers */
@@ -1374,13 +1374,13 @@ do_top(clientenv *clenv, msgnode *mnode, long lines)
            fdbflushw(fdb);
            if (msgwrite(fdb, mdata.body, tmp - mdata.body)) {
                if ((fdbwrite(fdb, "\r\n.\r\n", 5)) == 5) {
-                   /* mnode->retreived = TRUE; */
-                   ok = TRUE;
+                   /* mnode->retreived = true; */
+                   ok = true;
                }
            }
            if (!ok) {
                if ((fdbwrite(fdb, "\r\n.\r\n", 5)) == 5)
-                   ok = TRUE;
+                   ok = true;
            }
        }
        do_message_free(&mdata);
@@ -1396,7 +1396,7 @@ do_page(clientenv *clenv, msgnode *mnode, long page, long lines)
 {
     register char *tmp, *from, *to;
     fdbuf *fdb = clenv->fdb;
-    bool ok = FALSE;
+    bool ok = false;
     long lfrom, i;
     msgdata mdata;
 
@@ -1407,7 +1407,7 @@ do_page(clientenv *clenv, msgnode *mnode, long page, long lines)
        lfrom = (page - 1) * lines;
 
     if (do_message_load(&mdata, mnode)) {
-       if (reply(clenv, TRUE, "%lu octets", mdata.size)) {
+       if (reply(clenv, true, "%lu octets", mdata.size)) {
            /* Find out where starts and ends wanted range */
            i = lfrom;
            to = tmp = mdata.body;
@@ -1431,13 +1431,13 @@ do_page(clientenv *clenv, msgnode *mnode, long page, long lines)
                    fdbflushw(fdb);
                    if (msgwrite(fdb, from, to - from)) {
                        if ((fdbwrite(fdb, "\r\n.\r\n", 5)) == 5)
-                           ok = TRUE;
+                           ok = true;
                    }
                }
            }
            if (!ok) {
                if ((fdbwrite(fdb, "\r\n.\r\n", 5)) == 5)
-                   ok = TRUE;
+                   ok = true;
            }
        }
        do_message_free(&mdata);
@@ -1455,7 +1455,7 @@ do_page(clientenv *clenv, msgnode *mnode, long page, long lines)
 static bool
 do_update(clientenv *clenv)
 {
-    bool       ok = TRUE;
+    bool       ok = true;
     long       i, t;
     msgnode    *mnode;
     PGresult   *pgres;
@@ -1467,7 +1467,7 @@ do_update(clientenv *clenv)
        if ((pgres = PQexec(clenv->pgconn, "BEGIN")))
            PQclear(pgres);
        else
-           return FALSE;
+           return false;
 
        /*
         * Delete messages that were marked;
@@ -1485,7 +1485,7 @@ do_update(clientenv *clenv)
                        NULL, 0)) != NULL)
                    PQclear(pgres);
                else {
-                   ok = FALSE;
+                   ok = false;
                    break;
                }
            } else if (mnode[i].retreived) {
@@ -1496,7 +1496,7 @@ do_update(clientenv *clenv)
                        params, NULL, NULL, 0)) != NULL)
                    PQclear(pgres);
                else {
-                   ok = FALSE;
+                   ok = false;
                    break;
                }
            }
@@ -1506,7 +1506,7 @@ do_update(clientenv *clenv)
            if ((pgres = PQexec(clenv->pgconn, "COMMIT")) != NULL)
                PQclear(pgres);
            else
-               ok = FALSE;
+               ok = false;
        }
        if (!ok) {
            if ((pgres = PQexec(clenv->pgconn, "ROLLBACK")) != NULL)
@@ -1527,7 +1527,7 @@ msgwrite(fdbuf *fdb, const void *buf, size_t size)
 {
     const char *from, *from2, *to, *to2;
     ssize_t l = 0;
-    bool ok = TRUE;
+    bool ok = true;
 
     from = from2 = buf;
     to = to2 = buf + size;
@@ -1546,7 +1546,7 @@ msgwrite(fdbuf *fdb, const void *buf, size_t size)
     if (from2 < to2)
        l = fdbrwrite(fdb, from2, to2 - from2);
     if (l < 1)
-       ok = FALSE;
+       ok = false;
 
     return (ok);
 }
@@ -1593,7 +1593,7 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
 
 
     if ((fdb = fdbopen(&gfdf, &fdbc, fd, 8192, 8192, CONF.BANDWIDTH_IN * 1024,
-                   CONF.BANDWIDTH_OUT * 1024, timeout, timeout, FALSE))
+                   CONF.BANDWIDTH_OUT * 1024, timeout, timeout, false))
            != NULL) {
 
        /* Allocate our clientenv to share with state functions */
@@ -1611,11 +1611,11 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
            clenv->pgconn = utdata;
            clenv->retreived = clenv->deleted = 0;
            clenv->last = 0;
-           clenv->login = FALSE;
+           clenv->login = false;
            clenv->mailbox = NULL;
            clenv->index = NULL;
 
-           reply(clenv, TRUE, "%s (%s (%s)) Service ready",
+           reply(clenv, true, "%s (%s (%s)) Service ready",
                    iface->hostname, DAEMON_NAME, DAEMON_VERSION);
            state = STATE_AUTH;
            dstatus = MMS_NORMAL;
@@ -1631,11 +1631,11 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
                uint32_t chash;
 
                fdbflushw(fdb);
-               if ((len = fdbgets(fdb, buffer, 1023, FALSE)) > -1) {
+               if ((len = fdbgets(fdb, buffer, 1023, false)) > -1) {
 
                    /* If there were too many errors, exit accordingly */
                    if (clenv->errors > CONF.MAX_ERRORS) {
-                       reply(clenv, FALSE, "Too many errors");
+                       reply(clenv, false, "Too many errors");
                        dstatus = MMS_MANY_ERRORS;
                        break;
                    }
@@ -1670,7 +1670,7 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
 
                    } else {
                        mmsyslog(3, LOGLEVEL, "%08lX < %s", id, buffer);
-                       if (!reply(clenv, FALSE,
+                       if (!reply(clenv, false,
                                    "Syntax error or unknown command"))
                            break;
                        REGISTER_ERROR(clenv);
@@ -1697,15 +1697,15 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
            data_in = FDBBYTESR(fdb);
            data_out = FDBBYTESW(fdb);
 
-           mmstat_transact(&clenv->vstat, TRUE);
+           mmstat_transact(&clenv->vstat, true);
            if (clenv->mailbox != NULL)
                mmstat(&clenv->vstat, STAT_UPDATE, -1, "mmpop3d|who|%s",
                        clenv->mailbox);
            mmstat(&clenv->vstat, STAT_UPDATE, -1,
                    "mmpop3d|current|connections");
-           mmstat_transact(&clenv->vstat, FALSE);
+           mmstat_transact(&clenv->vstat, false);
 
-           mmstat_transact(&clenv->pstat, TRUE);
+           mmstat_transact(&clenv->pstat, true);
            if (clenv->mailbox != NULL && clenv->login) {
                char *domptr;
 
@@ -1745,7 +1745,7 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
                    "mmpop3d|total|bytes-in");
            mmstat(&clenv->pstat, STAT_UPDATE, data_out,
                    "mmpop3d|total|bytes-out");
-           mmstat_transact(&clenv->pstat, FALSE);
+           mmstat_transact(&clenv->pstat, false);
 
            /* Free our state-shared clenv */
            clenv = free_clientenv(clenv);
@@ -1789,7 +1789,7 @@ thread_mutex_create(void)
     struct mutexnode *mnod;
 
     pthread_mutex_lock(&mutexes_lock);
-    mnod = (struct mutexnode *)pool_alloc(&mutexes_pool, FALSE);
+    mnod = (struct mutexnode *)pool_alloc(&mutexes_pool, false);
     pthread_mutex_unlock(&mutexes_lock);
 
     if (mnod != NULL)
@@ -1835,9 +1835,9 @@ static bool
 thread_eintr(void)
 {
     if (errno == EINTR)
-       return TRUE;
+       return true;
 
-    return FALSE;
+    return false;
 }
 
 
@@ -1858,11 +1858,11 @@ async_checkpw(struct async_msg *msg)
     
     if ((hash = crypt(amsg->un.args.passwd, amsg->un.args.hash)) != NULL) {
        if ((mm_strcmp(hash, amsg->un.args.hash)) == 0)
-           amsg->un.res.matching = TRUE;
+           amsg->un.res.matching = true;
        else
-           amsg->un.res.matching = FALSE;
+           amsg->un.res.matching = false;
     } else  
-       amsg->un.res.matching = FALSE;
+       amsg->un.res.matching = false;
 }
 
 
index 61fe75f..110466e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmpop3d.h,v 1.33 2011/02/08 00:56:57 mmondor Exp $ */
+/* $Id: mmpop3d.h,v 1.34 2012/07/10 05:07:48 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2008, Matthew Mondor
@@ -68,7 +68,7 @@
 /* DEFINITIONS */
 
 #define DAEMON_NAME    "mmpop3d"
-#define DAEMON_VERSION "mmmail-0.3.4"
+#define DAEMON_VERSION "mmmail-0.3.5"
 
 /* Negative states are used by the state swapper, others are real states */
 #define STATE_ERROR    -3
index 307125f..71339d4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.c,v 1.111 2011/02/08 00:56:59 mmondor Exp $ */
+/* $Id: mmsmtpd.c,v 1.112 2012/07/10 05:07:50 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2008, Matthew Mondor
@@ -86,7 +86,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2001-2007\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmsmtpd.c,v 1.111 2011/02/08 00:56:59 mmondor Exp $");
+MMRCSID("$Id: mmsmtpd.c,v 1.112 2012/07/10 05:07:50 mmondor Exp $");
 
 
 
@@ -381,25 +381,25 @@ main(int argc, char **argv)
     CONF.FLOOD_MESSAGES = 20;
     CONF.FLOOD_EXPIRES = 30;
     CONF.FLOOD_CACHE = 100;
-    CONF.RESOLVE_HOSTS = FALSE;
-    CONF.RESOLVE_HELO = FALSE;
-    CONF.RESOLVE_MX_MAIL = FALSE;
-    CONF.RESOLVE_MX_RCPT = FALSE;
-    CONF.REQUIRE_HELO = FALSE;
-    CONF.REQUIRE_HOP = FALSE;
-    CONF.FLOOD_PROTECTION = TRUE;
-    CONF.STATFAIL_HELO = TRUE;
-    CONF.STATFAIL_NOHELO = TRUE;
-    CONF.STATFAIL_NOFROM = TRUE;
-    CONF.STATFAIL_ADDRESS = TRUE;
-    CONF.STATFAIL_RELAY = TRUE;
-    CONF.STATFAIL_FLOOD = TRUE;
-    CONF.STATFAIL_FULL = TRUE;
-    CONF.STATFAIL_TIMEOUT = TRUE;
-    CONF.STATFAIL_EOF = TRUE;
-    CONF.STATFAIL_FILTER = TRUE;
-    CONF.DELAY_ON_ERROR = FALSE;
-    CONF.RELAYING = FALSE;
+    CONF.RESOLVE_HOSTS = false;
+    CONF.RESOLVE_HELO = false;
+    CONF.RESOLVE_MX_MAIL = false;
+    CONF.RESOLVE_MX_RCPT = false;
+    CONF.REQUIRE_HELO = false;
+    CONF.REQUIRE_HOP = false;
+    CONF.FLOOD_PROTECTION = true;
+    CONF.STATFAIL_HELO = true;
+    CONF.STATFAIL_NOHELO = true;
+    CONF.STATFAIL_NOFROM = true;
+    CONF.STATFAIL_ADDRESS = true;
+    CONF.STATFAIL_RELAY = true;
+    CONF.STATFAIL_FLOOD = true;
+    CONF.STATFAIL_FULL = true;
+    CONF.STATFAIL_TIMEOUT = true;
+    CONF.STATFAIL_EOF = true;
+    CONF.STATFAIL_FILTER = true;
+    CONF.DELAY_ON_ERROR = false;
+    CONF.RELAYING = false;
 
     /* Advertize */
     printf("\r\n+++ %s (%s)\r\n\r\n", DAEMON_NAME, DAEMON_VERSION);
@@ -484,11 +484,11 @@ main(int argc, char **argv)
     {
        mmstat_t vstat;
 
-       mmstat_init(&vstat, TRUE, TRUE);
-       mmstat_transact(&vstat, TRUE);
+       mmstat_init(&vstat, true, true);
+       mmstat_transact(&vstat, true);
        mmstat(&vstat, STAT_DELETE, 0, "mmsmtpd|current|connections");
        mmstat(&vstat, STAT_DELETE, 0, "mmsmtpd|who|*");
-       mmstat_transact(&vstat, FALSE);
+       mmstat_transact(&vstat, false);
     }
     res_init();
 
@@ -523,7 +523,7 @@ main(int argc, char **argv)
        pool_init(&hosts_pool, "hosts_pool", malloc, free, NULL, NULL,
                sizeof(hostnode), CONF.FLOOD_CACHE, 1, 1);
        hashtable_init(&hosts_table, "hosts_table", CONF.FLOOD_CACHE, 1,
-               malloc, free, mm_memcmp, mm_memhash32, FALSE);
+               malloc, free, mm_memcmp, mm_memhash32, false);
        pthread_create(&hosts_table_thread, &threadattr, hosts_expire_thread,
                       NULL);
     }
@@ -566,11 +566,11 @@ main(int argc, char **argv)
        pthread_join(mmmail_db_gc_thread, NULL);
     }
     if (HASHTABLE_VALID(&command_table))
-       hashtable_destroy(&command_table, FALSE);
+       hashtable_destroy(&command_table, false);
     if (POOL_VALID(&command_pool))
        pool_destroy(&command_pool);
     if (HASHTABLE_VALID(&hosts_table))
-       hashtable_destroy(&hosts_table, FALSE);
+       hashtable_destroy(&hosts_table, false);
     if (POOL_VALID(&mutexes_pool))
        pool_destroy(&mutexes_pool);
     if (POOL_VALID(&hosts_pool))
@@ -592,7 +592,7 @@ main(int argc, char **argv)
 static int
 all_noop(clientenv *clenv)
 {
-    reply(clenv, 250, FALSE, "Ok, nothing performed");
+    reply(clenv, 250, false, "Ok, nothing performed");
 
     return (STATE_CURRENT);
 }
@@ -604,12 +604,12 @@ all_rset(clientenv *clenv)
     int nextstate = STATE_CURRENT;
 
     if (clenv->buffer[4] == 0) {
-       if (!init_clientenv(clenv, TRUE))
+       if (!init_clientenv(clenv, true))
            nextstate = STATE_ERROR;
        else
-           reply(clenv, 250, FALSE, "Reset state");
+           reply(clenv, 250, false, "Reset state");
     } else {
-       reply(clenv, 550, FALSE, "Command syntax error");
+       reply(clenv, 550, false, "Command syntax error");
        REGISTER_ERROR(clenv);
     }
 
@@ -620,7 +620,7 @@ all_rset(clientenv *clenv)
 static int
 all_quit(clientenv *clenv)
 {
-    reply(clenv, 221, FALSE, "%s closing connection",
+    reply(clenv, 221, false, "%s closing connection",
            clenv->iface->hostname);
 
     return (STATE_END);
@@ -645,15 +645,15 @@ all_help(clientenv *clenv)
                    &chash, sizeof(uint32_t));
        col = 0;
        if (nod != NULL) {
-           reply(clenv, 214, TRUE, nod->command->args);
-           reply(clenv, 214, TRUE, "   %s", nod->command->desc);
+           reply(clenv, 214, true, nod->command->args);
+           reply(clenv, 214, true, "   %s", nod->command->desc);
            col = 2;
        }
 
        if (col > 0)
-           reply(clenv, 214, FALSE, "End of HELP information");
+           reply(clenv, 214, false, "End of HELP information");
        else {
-           reply(clenv, 504, FALSE, "Unknown HELP topic");
+           reply(clenv, 504, false, "Unknown HELP topic");
            REGISTER_ERROR(clenv);
        }
 
@@ -661,7 +661,7 @@ all_help(clientenv *clenv)
        register int i;
 
        /* No, display the topics */
-       reply(clenv, 214, TRUE, "Available topics:");
+       reply(clenv, 214, true, "Available topics:");
        fdbwrite(clenv->fdb, "214-", 4);
        col = 1;
        for (i = 0; (tmp = commands[i].name) != NULL; i++) {
@@ -676,8 +676,8 @@ all_help(clientenv *clenv)
        }
        fdbwrite(clenv->fdb, "\r\n", 2);
 
-       reply(clenv, 214, TRUE, "For more information, use HELP <topic>");
-       reply(clenv, 214, FALSE, "End of HELP information");
+       reply(clenv, 214, true, "For more information, use HELP <topic>");
+       reply(clenv, 214, false, "End of HELP information");
     }
 
     return (STATE_CURRENT);
@@ -692,24 +692,24 @@ all_helo(clientenv *clenv)
     if ((mm_straspl(args, cmdline, 2)) == 2) {
        if (clenv->helo == NULL) {
            if (valid_host(clenv, args[1],
-                       CONF.RESOLVE_HELO ? HOST_RES : HOST_NORES, TRUE,
-                       TRUE) &&
+                       CONF.RESOLVE_HELO ? HOST_RES : HOST_NORES, true,
+                       true) &&
                    ((clenv->helo = mmstrdup(args[1])) != NULL)) {
-               reply(clenv, 250, FALSE, "%s ok", clenv->iface->hostname);
+               reply(clenv, 250, false, "%s ok", clenv->iface->hostname);
            } else {
                if (CONF.STATFAIL_HELO)
                    mmstat(&clenv->pstat, STAT_UPDATE, 1,
                            "mmsmtpd|failed|helo|%s",
                            clenv->c_ipaddr);
-               reply(clenv, 501, FALSE, "Invalid hostname");
+               reply(clenv, 501, false, "Invalid hostname");
                REGISTER_ERROR(clenv);
            }
        } else {
-           reply(clenv, 503, FALSE, "Duplicate HELO, use RSET or proceed");
+           reply(clenv, 503, false, "Duplicate HELO, use RSET or proceed");
            REGISTER_ERROR(clenv);
        }
     } else {
-       reply(clenv, 550, FALSE, "Command syntax error");
+       reply(clenv, 550, false, "Command syntax error");
        REGISTER_ERROR(clenv);
     }
 
@@ -735,7 +735,7 @@ all_mail(clientenv *clenv)
                    mmstat(&clenv->pstat, STAT_UPDATE, 1,
                            "mmsmtpd|failed|nohelo|%s",
                            clenv->c_ipaddr);
-               reply(clenv, 503, FALSE, "Use HELO first");
+               reply(clenv, 503, false, "Use HELO first");
                REGISTER_ERROR(clenv);
                return STATE_CURRENT;
            }
@@ -768,16 +768,16 @@ all_mail(clientenv *clenv)
 
        if (valid) {
            if ((clenv->from = mmstrdup(addr)) != NULL)
-               reply(clenv, 250, FALSE, "Sender ok");
+               reply(clenv, 250, false, "Sender ok");
            else
                nextstate = STATE_ERROR;
        } else {
-           reply(clenv, 501, FALSE, "Invalid address");
+           reply(clenv, 501, false, "Invalid address");
            REGISTER_ERROR(clenv);
        }
 
     } else {
-       reply(clenv, 503, FALSE, "Sender already specified");
+       reply(clenv, 503, false, "Sender already specified");
        REGISTER_ERROR(clenv);
     }
 
@@ -800,7 +800,7 @@ all_rcpt(clientenv *clenv)
      * be avoided for clarity. Functions could also be used but it has not
      * been necessary this far, and we want the code performance to be optimal.
      */
-    relay = FALSE;
+    relay = false;
 
     if (clenv->from == NULL) {
        reason = RCPT_NOFROM;
@@ -830,7 +830,7 @@ all_rcpt(clientenv *clenv)
      * an existing mailbox. <addr> is not modified if there exist no alias for
      * the address. Otherwise, <foraddr> keeps the original address.
      */
-    valid = FALSE;
+    valid = false;
     (void) mm_strcpy(foraddr, addr);
     if (!(valid = local_address(clenv, &boxinfo, addr))) {
        if (check_alias(clenv, addr)) {
@@ -857,12 +857,12 @@ all_rcpt(clientenv *clenv)
 
                for (domain = foraddr; *domain != '@'; domain++) ;
                domain++;
-               if (!valid_host(clenv, domain, HOST_RES_MX, FALSE, FALSE)) {
+               if (!valid_host(clenv, domain, HOST_RES_MX, false, false)) {
                    reason = RCPT_INVALID;
                    goto end;
                }
            }
-           relay = TRUE;
+           relay = true;
        }
     }
     if (!valid) {
@@ -932,7 +932,7 @@ all_rcpt(clientenv *clenv)
        }
     }
 
-    /* If CONF.FLOOD_PROTECTION is TRUE, make sure that we respect the rate
+    /* If CONF.FLOOD_PROTECTION is true, make sure that we respect the rate
      * of CONF.FLOOD_MESSAGES within CONF.FLOOD_EXPIRES for this client.
      */
     if (CONF.FLOOD_PROTECTION) {
@@ -946,28 +946,28 @@ all_rcpt(clientenv *clenv)
            entry = clenv->c_ipaddr;
        len = mm_strlen(entry);
 
-       valid = TRUE;
+       valid = true;
        pthread_mutex_lock(&hosts_lock);
        /* First acquire our hostnode, or create it if required */
        if ((hnod = (hostnode *)hashtable_lookup(&hosts_table, entry, len + 1))
                == NULL) {
            /* Create a new entry */
-           if ((hnod = (hostnode *)pool_alloc(&hosts_pool, FALSE)) != NULL) {
+           if ((hnod = (hostnode *)pool_alloc(&hosts_pool, false)) != NULL) {
                mm_memcpy(hnod->host, entry, len + 1);
                LR_INIT(&hnod->lr, CONF.FLOOD_MESSAGES,
                        CONF.FLOOD_EXPIRES * 60, time(NULL));
                hashtable_link(&hosts_table, (hashnode_t *)hnod, entry,
-                       len + 1, FALSE);
+                       len + 1, false);
            } else {
-               valid = FALSE;
+               valid = false;
                reason = RCPT_FLOOD;
                mmsyslog(0, LOGLEVEL, "FLOOD_CACHE not large enough");
            }
        }
        if (valid) {
            /* Check and update limits */
-           if (!lr_allow(&hnod->lr, 1, 0, FALSE)) {
-               valid = FALSE;
+           if (!lr_allow(&hnod->lr, 1, 0, false)) {
+               valid = false;
                reason = RCPT_FLOOD;
                mmsyslog(0, LOGLEVEL,
                        "%08lX Considered flood and rejected (%ld message(s) "
@@ -992,13 +992,14 @@ all_rcpt(clientenv *clenv)
 
        reason = RCPT_ERROR;
        pthread_mutex_lock(&rcpt_lock);
-       rnode = (rcptnode *)pool_alloc(&rcpt_pool, FALSE);
+       rnode = (rcptnode *)pool_alloc(&rcpt_pool, false);
        pthread_mutex_unlock(&rcpt_lock);
        if (rnode != NULL) {
            mm_strcpy(rnode->address, (relay ? foraddr : addr));
            mm_strcpy(rnode->foraddress, foraddr);
            rnode->hash = ahash;
            rnode->relay = relay;
+           rnode->list = boxinfo.list;
            DLIST_APPEND(&clenv->rcpt, (node_t *)rnode);
            reason = RCPT_OK;
            clenv->rcpts++;
@@ -1013,7 +1014,7 @@ end:
     /* Reply with appropriate message */
     if (reason != RCPT_OK)
        REGISTER_ERROR(clenv);
-    reply(clenv, rcpt_msg[reason].code, FALSE, rcpt_msg[reason].msg);
+    reply(clenv, rcpt_msg[reason].code, false, rcpt_msg[reason].msg);
 
     return (nextstate);
 }
@@ -1032,15 +1033,15 @@ all_data(clientenv *clenv)
                else
                    clenv->messages++;
            } else {
-               reply(clenv, 502, FALSE, "Use RCPT first");
+               reply(clenv, 502, false, "Use RCPT first");
                REGISTER_ERROR(clenv);
            }
        } else {
-           reply(clenv, 503, FALSE, "Use MAIL and RCPT first");
+           reply(clenv, 503, false, "Use MAIL and RCPT first");
            REGISTER_ERROR(clenv);
        }
     } else {
-       reply(clenv, 550, FALSE, "Command syntax error");
+       reply(clenv, 550, false, "Command syntax error");
        REGISTER_ERROR(clenv);
     }
 
@@ -1051,7 +1052,7 @@ all_data(clientenv *clenv)
 static int
 all_beer(clientenv *clenv)
 {
-    reply(clenv, 420, FALSE, "Here, enjoy!");
+    reply(clenv, 420, false, "Here, enjoy!");
 
     return (STATE_CURRENT);
 }
@@ -1066,32 +1067,32 @@ hash_commands(struct command *cmd, size_t min)
     int i;
 
     /* We do not care for any unfreed resources, the program will free them
-     * and exit if we return FALSE.
+     * and exit if we return false.
      */ 
     if (!pool_init(&command_pool, "command_pool", malloc, free, NULL, NULL,
                sizeof(struct commandnode), 64, 1, 0) ||
            !hashtable_init(&command_table, "command_table", 64, 1, malloc,
-                   free, commandnode_keycmp, commandnode_keyhash, TRUE))
-       return FALSE;
+                   free, commandnode_keycmp, commandnode_keyhash, true))
+       return false;
 
     for (i = 0; cmd->name != NULL; cmd++, i++) {
        struct commandnode *nod;
        
-       if ((nod = (struct commandnode *)pool_alloc(&command_pool, FALSE))
+       if ((nod = (struct commandnode *)pool_alloc(&command_pool, false))
                == NULL)
-           return FALSE;
+           return false;
        if ((nod->hash = mm_strpack32(cmd->name, min)) == 0)
-           return FALSE;
+           return false;
        nod->command = cmd;
        nod->index = i;
        if (!hashtable_link(&command_table, (hashnode_t *)nod, &nod->hash,
-                   sizeof(uint32_t), TRUE)) {
+                   sizeof(uint32_t), true)) {
            DEBUG_PRINTF("hash_commands", "hashtable_link(%s)", cmd->name);
-           return FALSE;
+           return false;
        }
     }
 
-    return TRUE;
+    return true;
 }               
 
 
@@ -1117,7 +1118,7 @@ commandnode_keycmp(const void *src, const void *dst, size_t len)
 
 
 /* Function used to return standard RFC result strings to the client,
- * and returns FALSE on error.
+ * and returns false on error.
  * NOTE: As we are no longer calling write() directly, but fdbprintf()
  * buffering function instead, it is no longer necessary to check the reply()
  * return value each time it is called. We made sure to ignore SIGPIPE,
@@ -1129,7 +1130,7 @@ reply(clientenv *clenv, int code, bool cont, const char *fmt, ...)
 {
     char buf[1024];
     va_list arg_ptr;
-    bool err = TRUE;
+    bool err = true;
     fdbuf *fdb = clenv->fdb;
 
     *buf = 0;
@@ -1153,12 +1154,12 @@ clientenv_constructor(pnode_t *pn)
 {
     clientenv  *clenv = (clientenv *)pn;
 
-    mmstat_init(&clenv->vstat, TRUE, TRUE);
-    mmstat_init(&clenv->pstat, TRUE, FALSE);
+    mmstat_init(&clenv->vstat, true, true);
+    mmstat_init(&clenv->pstat, true, false);
     DLIST_INIT(&clenv->rcpt);
     clenv->helo = clenv->from = NULL;
 
-    return TRUE;
+    return true;
 }
 
 /* ARGSUSED */
@@ -1200,7 +1201,7 @@ alloc_clientenv(void)
     clientenv *clenv;
 
     pthread_mutex_lock(&clenv_lock);
-    clenv = (clientenv *)pool_alloc(&clenv_pool, FALSE);
+    clenv = (clientenv *)pool_alloc(&clenv_pool, false);
     pthread_mutex_unlock(&clenv_lock);
 
     return (clenv);
@@ -1208,7 +1209,7 @@ alloc_clientenv(void)
 
 
 /* Useful on RSET to reset initial clenv state,
- * returns TRUE on success or FALSE on error
+ * returns true on success or false on error
  */
 static bool
 init_clientenv(clientenv *clenv, bool helo)
@@ -1219,7 +1220,7 @@ init_clientenv(clientenv *clenv, bool helo)
        clenv->from = mmstrfree(clenv->from);
     empty_rcpts(&clenv->rcpt);
 
-    return (TRUE);
+    return (true);
 }
 
 
@@ -1262,13 +1263,13 @@ empty_rcpts(list_t *lst)
 
 /* Checks in the list of aliases for any pattern matching the address, and
  * map it to the real address to redirect to, replacing supplied address.
- * The addr char array must at least be 64 bytes. Returns FALSE if no alias
- * exist for the address, or TRUE on success.
+ * The addr char array must at least be 64 bytes. Returns false if no alias
+ * exist for the address, or true on success.
  */
 static bool
 check_alias(clientenv *clenv, char *addr)
 {
-    bool       res = FALSE;
+    bool       res = false;
     char       oaddr[64], *user, *domain;
     PGresult   *pgres;
     const char *params[2];
@@ -1301,7 +1302,7 @@ check_alias(clientenv *clenv, char *addr)
        }
        if (max > -1) {
            (void) mm_strcpy(addr, a);
-           res = TRUE;
+           res = true;
        }
        PQclear(pgres);
     }
@@ -1310,7 +1311,7 @@ check_alias(clientenv *clenv, char *addr)
 }
 
 
-/* Depending on which is set of <addr> and/or <host>, returns TRUE if any
+/* Depending on which is set of <addr> and/or <host>, returns true if any
  * of both matched an entry.
  */
 static bool
@@ -1404,32 +1405,35 @@ best_match(const char *str, const char *pat)
 }
 
 
-/* Returns FALSE if this address doesn't exist in our local mailboxes.
+/* Returns false if this address doesn't exist in our local mailboxes.
  * Otherwise it populates boxinfo structure with information about the
  * mailbox.
  */
 static bool
 local_address(clientenv *clenv, struct box_info *boxinfo, const char *address)
 {
-    bool               res = FALSE;
+    bool               res = false;
     PGresult           *pgres;
     const char         *params[2];
 
     params[0] = address;
     params[1] = NULL;
     if ((pgres = PQexecParams(clenv->pgconn,
-           "SELECT max_size,size,max_msgs,msgs,filter,filter_type FROM box "
-           "WHERE address=$1", 1, NULL, params, NULL, NULL, 0)) != NULL) {
+           "SELECT max_size,size,max_msgs,msgs,filter,filter_type,list "
+           "FROM box WHERE address=$1",
+           1, NULL, params, NULL, NULL, 0)) != NULL) {
        if (PQntuples(pgres) == 1) {
            boxinfo->max_size = atol(PQgetvalue(pgres, 0, 0));
            boxinfo->size = atol(PQgetvalue(pgres, 0, 1));
            boxinfo->max_msgs = atol(PQgetvalue(pgres, 0, 2));
            boxinfo->msgs = atol(PQgetvalue(pgres, 0, 3));
            boxinfo->filter = (*(PQgetvalue(pgres, 0, 4)) == 't' ?
-                   TRUE : FALSE);
+                   true : false);
            boxinfo->filter_type = (*(PQgetvalue(pgres, 0, 5)) == 't' ?
-                   TRUE : FALSE);
-           res = TRUE;
+                   true : false);
+           boxinfo->list = (*(PQgetvalue(pgres, 0, 6)) == 't' ?
+                   true : false);
+           res = true;
        }
        PQclear(pgres);
     }
@@ -1509,25 +1513,25 @@ valid_address(clientenv *clenv, char *to, size_t len, char *addr, int res)
     /* First locate required @ */
     for (ptr = addr; *ptr != '\0' && *ptr != '@'; ptr++) ;
     if (*ptr == '\0')
-       return (FALSE);
+       return (false);
     h = ptr + 1;
     /* Then scan to the left */
     for (ptr--; ptr >= addr && VALID_ADDR_CHAR(*ptr); ptr--) ;
     if (h - ptr < 3 || ptr < addr)
-       return (FALSE);
+       return (false);
     a = ++ptr;
     /* Now to the right */
     for (ptr = h; *ptr != '\0' && VALID_ADDR_CHAR(*ptr); ptr++) ;
     if (ptr - h < 2)
-       return (FALSE);
+       return (false);
     *ptr = '\0';
     /* Now validate hostname part */
-    if (valid_host(clenv, h, res, FALSE, TRUE)) {
+    if (valid_host(clenv, h, res, false, true)) {
        mm_strncpy(to, a, len - 1);
-       return (TRUE);
+       return (true);
     }
 
-    return (FALSE);
+    return (false);
 }
 
 
@@ -1536,7 +1540,7 @@ valid_host(clientenv *clenv, char *host, int res, bool addr, bool sanity)
 {
 
     if (addr && res != HOST_RES_MX && valid_ipaddress(clenv, host))
-       return TRUE;
+       return true;
 
     if (sanity) {
        register char *ptr;
@@ -1546,7 +1550,7 @@ valid_host(clientenv *clenv, char *host, int res, bool addr, bool sanity)
        /* First make sure all characters are valid */
        for (ptr = host; *ptr != '\0'; ptr++)
            if (!VALID_HOST_CHAR(*ptr))
-               return FALSE;
+               return false;
 
        /* Now verify that all parts of the hostname are starting with
         * an alphanumeric char
@@ -1554,7 +1558,7 @@ valid_host(clientenv *clenv, char *host, int res, bool addr, bool sanity)
        ptr = host;
        while (*ptr != '\0') {
            if (!isalnum((int)*ptr))
-               return FALSE;
+               return false;
            /* Find next host part */
            while (*ptr != '\0' && *ptr != '.') ptr++;
            if (*ptr == '.') {
@@ -1576,18 +1580,18 @@ valid_host(clientenv *clenv, char *host, int res, bool addr, bool sanity)
            /* Check for an MX DNS IP address entry for it */
            if ((a_res_query(clenv, host, C_IN, T_MX, answer,
                            sizeof(answer) - 1)) == -1)
-               return FALSE;
+               return false;
        } else if (res == HOST_RES) {
            /* Check if hostname resolves to normal A/AAAA record */
            if (a_res_query(clenv, host, C_IN, T_A, answer,
                        sizeof(answer) - 1) == -1 &&
                    a_res_query(clenv, host, C_IN, T_AAAA, answer,
                        sizeof(answer) - 1) == -1)
-               return FALSE;
+               return false;
        }
     }
 
-    return TRUE;
+    return true;
 }
 
 
@@ -1599,9 +1603,9 @@ valid_ipaddress(clientenv *clenv, const char *addr)
 
     if (inet_pton(*(SERVER_SOCKADDR_FAMILY(&clenv->iface->address)), addr,
                    SERVER_SOCKADDR(&saddr)) == 1)
-       return TRUE;
+       return true;
 
-    return FALSE;
+    return false;
 }
 
 
@@ -1677,12 +1681,14 @@ validate_msg_line(char *line, ssize_t *len, int *res, void *udata)
            }
        }
        /* Drop html-only mail */
+       /*
        if (mm_strcmp(header, "CONTENT-TYPE") == 0) {
            if (best_match(data, "*text/html*") != -1) {
                *res = CFDBRB_HEADER;
                return FDBRB_STOP;
            }
        }
+       */
 
        /* Count number of Received: headers (SMTP hops) */
        if (mm_strcmp(header, "RECEIVED") == 0) {
@@ -1747,7 +1753,7 @@ validate_msg_line(char *line, ssize_t *len, int *res, void *udata)
 endheader:
 
     /* We reached end of headers */
-    ud->header = FALSE;
+    ud->header = false;
 
     /* Drop if we require at least one hop but got none */
     if (CONF.REQUIRE_HOP && ud->hops == 0) {
@@ -1756,7 +1762,8 @@ endheader:
     }
 
     {
-       char    tline[1024], tdata[64], *cptr, *tptr;
+       char            tline[1024], tdata[64], *cptr, *tptr;
+       clientenv       *clenv = ud->clenv;
 
        /* Create the headers we consider mendatory if they were not supplied.
         * We append them after all headers that were supplied, this way the
@@ -1772,8 +1779,8 @@ endheader:
            tptr = cptr;
            iso_time(tdata);
            cptr += snprintf(cptr, 1023, "Message-Id: <%s.%08lX%02lX@%s>\r\n",
-                   tdata, ud->clenv->id, ud->clenv->messages,
-                   ud->clenv->iface->hostname);
+                   tdata, clenv->id, clenv->messages,
+                   clenv->iface->hostname);
            ud->h_id = mmstrdup(&tptr[12]);
            ud->h_id[cptr - tptr - 14] = '\0';
        }
@@ -1786,7 +1793,7 @@ endheader:
            tptr = cptr;
            cptr[1024 - (cptr - tline)] = '\0';
            cptr += snprintf(cptr, 1023 - (cptr - tline), "From: %s\r\n",
-                   ud->clenv->from);
+                   clenv->from);
            ud->h_from = mmstrdup(&tptr[6]);
            ud->h_from[cptr - tptr - 8] = '\0';
        }
@@ -1827,7 +1834,7 @@ endheader:
 
 
 /* This function is called by STATE_DATA and permits the client to send
- * the message data, respecting expected limits. Returns FALSE if the state
+ * the message data, respecting expected limits. Returns false if the state
  * should switch to STATE_ERROR, on fatal error (i.e. out of memory)
  */
 static bool
@@ -1835,10 +1842,10 @@ do_data(clientenv *clenv)
 {
     struct fdbrb_buffer *fdbrb;
     int res, err = DATA_INTERNAL;
-    bool ok = FALSE;
+    bool ok = false;
     struct validate_udata ud;
 
-    reply(clenv, data_msg[DATA_SUBMIT].code, FALSE,
+    reply(clenv, data_msg[DATA_SUBMIT].code, false,
            data_msg[DATA_SUBMIT].msg);
     fdbflushw(clenv->fdb);
 
@@ -1852,12 +1859,12 @@ do_data(clientenv *clenv)
      */
     ud.id = clenv->id;
     ud.hops = 0;
-    ud.msgid = ud.date = ud.from = ud.to = ud.subject = ud.inreply = FALSE;
-    ud.header = TRUE;
+    ud.msgid = ud.date = ud.from = ud.to = ud.subject = ud.inreply = false;
+    ud.header = true;
     ud.clenv = clenv;
     ud.h_from = ud.h_to = ud.h_subject = ud.h_id = ud.h_reply = NULL;
     res = fdbreadbuf(&fdbrb, clenv->fdb, 32768, 4096, CONF.MAX_DATA_SIZE,
-           CONF.MAX_DATA_LINES, validate_msg_line, &ud, FALSE);
+           CONF.MAX_DATA_LINES, validate_msg_line, &ud, false);
 
     /* Map results to DATA suitable ones */
     switch (res) {
@@ -1897,7 +1904,7 @@ do_data(clientenv *clenv)
        REGISTER_ERROR(clenv);
        break;
     case FDBRB_OK:
-       ok = TRUE;
+       ok = true;
        break;
     }
 
@@ -1918,10 +1925,10 @@ do_data(clientenv *clenv)
     fdbfreebuf(&fdbrb);        /* Internally only frees if not already freed */
     if (ok)
        err = DATA_OK;
-    reply(clenv, data_msg[err].code, FALSE, data_msg[err].msg);
+    reply(clenv, data_msg[err].code, false, data_msg[err].msg);
 
     /* Reset mail state (and free RCPTs) */
-    init_clientenv(clenv, FALSE);
+    init_clientenv(clenv, false);
 
     return (ok);
 }
@@ -1957,7 +1964,7 @@ do_data_stats(clientenv *clenv, rcptnode *rnode, size_t len)
 {
     char *domptr;
 
-    mmstat_transact(&clenv->pstat, TRUE);
+    mmstat_transact(&clenv->pstat, true);
 
     /* Record per-box statistics. Note that when aliases are used, the actual
      * target mailbox is used.
@@ -1977,21 +1984,21 @@ do_data_stats(clientenv *clenv, rcptnode *rnode, size_t len)
     mmstat(&clenv->pstat, STAT_UPDATE, len, "mmmail|domain|%s|bytes-in",
            domptr);
 
-    mmstat_transact(&clenv->pstat, FALSE);
+    mmstat_transact(&clenv->pstat, false);
 }
 
 
-/* Returns TRUE if the client address/hostname is allowed to relay messages
- * for non-local addresses, or FALSE otherwise, with reason set to either
+/* Returns true if the client address/hostname is allowed to relay messages
+ * for non-local addresses, or false otherwise, with reason set to either
  * RCPT_UNKNOWN (destination address on a locally handled domain but
  * unexisting) or RCPT_RELAY (relay denied for sender address/hostname).
- * If TRUE is returned, the post can be relayed, since it does not belong to
+ * If true is returned, the post can be relayed, since it does not belong to
  * any local domains we are handling and that the client has relaying rights.
  */
 bool
 address_relay_allow(clientenv *clenv, int *reason, const char *addr)
 {
-    bool       res = TRUE;
+    bool       res = true;
     const char *domain;
     PGresult   *pgres;
 
@@ -2010,7 +2017,7 @@ address_relay_allow(clientenv *clenv, int *reason, const char *addr)
 
        for (i = 0, t = PQntuples(pgres); i < t; i++) {
            if (best_match(domain, PQgetvalue(pgres, i, 0)) != -1) {
-               res = FALSE;
+               res = false;
                *reason = RCPT_UNKNOWN;
                break;
            }
@@ -2026,7 +2033,7 @@ address_relay_allow(clientenv *clenv, int *reason, const char *addr)
      * allowed to relay messages through us? Verify via the client's IP
      * address and/or hostname.
      */
-    res = FALSE;
+    res = false;
 
     if ((pgres = PQexec(clenv->pgconn, "SELECT pattern FROM relayfrom"))
            != NULL) {
@@ -2037,13 +2044,13 @@ address_relay_allow(clientenv *clenv, int *reason, const char *addr)
            pat = PQgetvalue(pgres, i, 0);
            if (clenv->c_ipaddr != NULL) {
                if (best_match(clenv->c_ipaddr, pat) != -1) {
-                   res = TRUE;
+                   res = true;
                    break;
                }
            }
            if (clenv->c_hostname != NULL) {
                if (best_match(clenv->c_hostname, pat) != -1) {
-                   res = TRUE;
+                   res = true;
                    break;
                }
            }
@@ -2085,14 +2092,19 @@ iso_time(char *str)
  */
 static bool
 message_write(char *path, const char *recvline, size_t recvlen,
-       struct fdbrb_buffer *fdbrb, const char *box)
+       struct fdbrb_buffer *fdbrb, rcptnode *rnode)
 {
-    bool       ok = FALSE;
-    char       filetime[16];
+    bool       ok = false;
+    char       filetime[16], *box = "relayqueue";
     int                i, fd;
     uint32_t   r;
+    bool       list = false;
 
     fd = -1;
+    if (rnode != NULL) {
+       box = rnode->address;
+       list = rnode->list;
+    }
 
     /* Make sure that directory exists, performing an mkdir(2) which will
      * fail if it already does.
@@ -2100,7 +2112,7 @@ message_write(char *path, const char *recvline, size_t recvlen,
     (void) snprintf(path, 255, "%s/%s", CONF.MAIL_DIR, box);
     if (mkdir(path, 00750) == -1 && errno != EEXIST) {
        mmsyslog(0, LOGLEVEL, "mkdir(%s) == %s", path, strerror(errno));
-       return FALSE;
+       return false;
     }
 
     /* Generate unique filename to store the message within the mail
@@ -2124,10 +2136,46 @@ message_write(char *path, const char *recvline, size_t recvlen,
      * performance.
      */
     if (fd != -1) {
-       if (write(fd, recvline, recvlen) == recvlen &&
-               write(fd, fdbrb->array, fdbrb->current) == fdbrb->current
-               && close(fd) == 0)
-           ok = TRUE;
+       struct iovec    iov[4];
+       size_t          total;
+       char            *body;
+
+       /* "Received:" header */
+       iov[0].iov_base = (void *)recvline;
+       iov[0].iov_len = recvlen;
+
+       /* Message headers */
+       body = strstr(fdbrb->array, "\r\n\r\n"); /* Should never be NULL */
+       body = &body[2];
+       iov[1].iov_base = fdbrb->array;
+       iov[1].iov_len = body - fdbrb->array;
+
+       /* Mailing list headers if needed */
+       if (rnode->list) {
+           char        lheads[1024], *cptr;
+
+           *lheads = '\0';
+           iov[2].iov_base = lheads;
+           iov[2].iov_len = snprintf(lheads, 1023,
+                   "List-Id: %s\r\nList-Post: <mailto:%s>\r\n",
+                   rnode->address, rnode->address);
+
+           for (cptr = lheads; *cptr != '\0' && *cptr != '@'; cptr++) ;
+           if (*cptr == '@')
+               *cptr = '.';
+       } else {
+           iov[2].iov_base = "";
+           iov[2].iov_len = 0;
+       }
+
+       /* Message body, prefixed with headers terminating empty line */
+       iov[3].iov_base = body;
+       iov[3].iov_len = fdbrb->current - (body - fdbrb->array);
+
+       total = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len +
+          iov[3].iov_len;
+       if (writev(fd, iov, 4) == total && close(fd) == 0)
+           ok = true;
        else {
            mmsyslog(0, LOGLEVEL, "write()/close()|(%s) == %s",
                    path, strerror(errno));
@@ -2155,7 +2203,7 @@ do_data_file(clientenv *clenv, struct fdbrb_buffer *fdbrb,
     size_t     recvlen;
     bool       ok;
 
-    ok = TRUE;
+    ok = true;
     rfc_time(smtptime);
 
     DLIST_FOREACH(&clenv->rcpt, rnode) {
@@ -2166,7 +2214,7 @@ do_data_file(clientenv *clenv, struct fdbrb_buffer *fdbrb,
            ok = do_data_queue_box(clenv, recvline, recvlen, fdbrb, rnode, ud);
        else {
            if (!CONF.RELAYING)
-               ok = FALSE;
+               ok = false;
            else
                ok = do_data_queue_relay(clenv, recvline, recvlen, fdbrb,
                        rnode);
@@ -2194,8 +2242,8 @@ do_data_queue_box(clientenv *clenv, const char *recvline, size_t recvlen,
      * lock might be wanted though, or a PostgreSQL advisory lock.
      */
 
-    if (!message_write(path, recvline, recvlen, fdbrb, rnode->address))
-       return FALSE;
+    if (!message_write(path, recvline, recvlen, fdbrb, rnode))
+       return false;
 
     (void) snprintf(v, 15, "%ld", (long)fdbrb->current + recvlen);
     params[0] = rnode->address;
@@ -2217,12 +2265,12 @@ do_data_queue_box(clientenv *clenv, const char *recvline, size_t recvlen,
        syslog(LOG_NOTICE, "do_date_queue_box() - PQexecParams()");
        (void) unlink(path);
 
-       return FALSE;
+       return false;
     }
 
     do_data_stats(clenv, rnode, fdbrb->current + recvlen);
 
-    return TRUE;
+    return true;
 }
 
 /* Queue a message for relaying */
@@ -2231,7 +2279,7 @@ do_data_queue_relay(clientenv *clenv, const char *recvline, size_t recvlen,
        struct fdbrb_buffer *fdbrb, rcptnode *rnode)
 {
     char       path[256], *user, *domain, *restore, v[16];
-    bool       ok = TRUE;
+    bool       ok = true;
     PGresult   *pgres;
     const char *params[7];
 
@@ -2248,7 +2296,7 @@ do_data_queue_relay(clientenv *clenv, const char *recvline, size_t recvlen,
     user = rnode->address;
     domain = &restore[1];
 
-    if (message_write(path, recvline, recvlen, fdbrb, "relayqueue")) {
+    if (message_write(path, recvline, recvlen, fdbrb, NULL)) {
        /* Message file saved successfully, add corresponding DB entry */
        (void) snprintf(v, 15, "%ld", (long)fdbrb->current + recvlen);
        params[0] = clenv->from;
@@ -2267,10 +2315,10 @@ do_data_queue_relay(clientenv *clenv, const char *recvline, size_t recvlen,
            syslog(LOG_NOTICE, "do_data_queue_relay() - PQexecParams()");
            (void) snprintf(path, 255, "%s/%s", CONF.MAIL_DIR, path);
            (void) unlink(path);
-           ok = FALSE;
+           ok = false;
        }
     } else
-       ok = FALSE;
+       ok = false;
 
     /* Restore string to original value */
     *restore = '@';
@@ -2289,12 +2337,12 @@ do_data_queue_relay(clientenv *clenv, const char *recvline, size_t recvlen,
 /*
  * Attempt to notify mmrelayd(8) that at least one message is ready in the
  * queue to route.
- * XXX Broken! Do not use RELAYING = TRUE yet!
+ * XXX Broken! Do not use RELAYING = true yet!
  */
 static void
 do_data_queue_notify(clientenv *clenv)
 {
-    bool               ok = FALSE;
+    bool               ok = false;
     /*
     notify_msg_t       msg;
     */
@@ -2334,7 +2382,7 @@ do_data_queue_notify(clientenv *clenv)
            if ((relayd_sock = do_data_queue_notify_connect()) != -1)
                continue;
        } else
-           ok = TRUE;
+           ok = true;
        break;
     }
 
@@ -2419,7 +2467,7 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
     time_start = time(NULL);
 
     if ((fdb = fdbopen(&gfdf, &fdbc, fd, 8192, 8192, CONF.BANDWIDTH_IN * 1024,
-                   CONF.BANDWIDTH_OUT * 1024, timeout, timeout, FALSE))
+                   CONF.BANDWIDTH_OUT * 1024, timeout, timeout, false))
            != NULL) {
 
        /* Allocate our clientenv to share with state functions */
@@ -2443,7 +2491,7 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
            DLIST_INIT(&clenv->rcpt);
            clenv->helo = clenv->from = NULL;
 
-           reply(clenv, 220, FALSE, "%s (%s (%s)) Service ready",
+           reply(clenv, 220, false, "%s (%s (%s)) Service ready",
                    iface->hostname, DAEMON_NAME, DAEMON_VERSION);
            state = STATE_ALL;
            dstatus = MMS_NORMAL;
@@ -2451,12 +2499,12 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
            mmstat(&clenv->pstat, STAT_UPDATE, 1,
                    "mmsmtpd|total|connections");
 
-           mmstat_transact(&clenv->vstat, TRUE);
+           mmstat_transact(&clenv->vstat, true);
            mmstat(&clenv->vstat, STAT_UPDATE, 1,
                    "mmsmtpd|current|connections");
            mmstat(&clenv->vstat, STAT_UPDATE, 1, "mmsmtpd|who|%s",
                    clenv->c_ipaddr);
-           mmstat_transact(&clenv->vstat, FALSE);
+           mmstat_transact(&clenv->vstat, false);
 
            /* Main state switcher loop */
            for (;;) {
@@ -2464,11 +2512,11 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
                register struct commandnode *nod;
 
                fdbflushw(fdb);
-               if ((len = fdbgets(fdb, buffer, 1023, FALSE)) > -1) {
+               if ((len = fdbgets(fdb, buffer, 1023, false)) > -1) {
 
                    /* If there were too many errors, exit accordingly */
                    if (clenv->errors > CONF.MAX_ERRORS) {
-                       reply(clenv, 421, FALSE, "Too many errors");
+                       reply(clenv, 421, false, "Too many errors");
                        dstatus = MMS_MANY_ERRORS;
                        break;
                    }
@@ -2496,14 +2544,14 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
                        } else {
                            /* Unimplemented command for this state */
                            REGISTER_ERROR(clenv);
-                           if (!reply(clenv, states[state].errcode, FALSE,
+                           if (!reply(clenv, states[state].errcode, false,
                                        states[state].errtext))
                                break;
                        }
 
                    } else {
                        mmsyslog(3, LOGLEVEL, "%08lX < %s", id, buffer);
-                       reply(clenv, 500, FALSE,
+                       reply(clenv, 500, false,
                                "Syntax error or unknown command, type HELP");
                        REGISTER_ERROR(clenv);
                    }
@@ -2532,21 +2580,21 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
            data_in = FDBBYTESR(fdb);
            data_out = FDBBYTESW(fdb);
 
-           mmstat_transact(&clenv->vstat, TRUE);
+           mmstat_transact(&clenv->vstat, true);
            mmstat(&clenv->vstat, STAT_UPDATE, -1,
                    "mmsmtpd|who|%s", clenv->c_ipaddr);
            mmstat(&clenv->vstat, STAT_UPDATE, -1,
                    "mmsmtpd|current|connections");
-           mmstat_transact(&clenv->vstat, FALSE);
+           mmstat_transact(&clenv->vstat, false);
 
-           mmstat_transact(&clenv->pstat, TRUE);
+           mmstat_transact(&clenv->pstat, true);
            mmstat(&clenv->pstat, STAT_UPDATE, messages_in,
                    "mmsmtpd|total|messages-in");
            mmstat(&clenv->pstat, STAT_UPDATE, data_in,
                    "mmsmtpd|total|bytes-in");
            mmstat(&clenv->pstat, STAT_UPDATE, data_out,
                    "mmsmtpd|total|bytes-out");
-           mmstat_transact(&clenv->pstat, FALSE);
+           mmstat_transact(&clenv->pstat, false);
 
            /* Free our state-shared clenv */
            clenv = free_clientenv(clenv);
@@ -2589,7 +2637,7 @@ thread_mutex_create(void)
     struct mutexnode *mnod;
 
     pthread_mutex_lock(&mutexes_lock);
-    mnod = (struct mutexnode *)pool_alloc(&mutexes_pool, FALSE);
+    mnod = (struct mutexnode *)pool_alloc(&mutexes_pool, false);
     pthread_mutex_unlock(&mutexes_lock);
 
     if (mnod != NULL)
@@ -2635,9 +2683,9 @@ static bool
 thread_eintr(void)
 {
     if (errno == EINTR)
-       return TRUE;
+       return true;
 
-    return FALSE;
+    return false;
 }
 
 
@@ -2733,7 +2781,7 @@ hosts_expire_thread_iterator(hashnode_t *hnod, void *udata)
            data->soonest = rem;
     }
 
-    return TRUE;
+    return true;
 }
 
 
@@ -2773,7 +2821,7 @@ db_gc_thread(void *args)
            continue;
        PQclear(pgres);
 
-       ok = TRUE;
+       ok = true;
        if ((pgres = PQexec(pgconn,
                "SELECT id,type,path FROM file_gc_queue ORDER BY id"))
                != NULL) {
@@ -2788,12 +2836,12 @@ db_gc_thread(void *args)
                                PQgetvalue(pgres, i, 2));
                if (*(PQgetvalue(pgres, i, 1)) == 'f') {
                    if (unlink(path) != 0) {
-                       ok = FALSE;
+                       ok = false;
                        goto skip;
                    }
                } else {
                    if (rmdir(path) != 0) {
-                       ok = FALSE;
+                       ok = false;
                        goto skip;
                    }
                }
@@ -2804,7 +2852,7 @@ skip:
                            "DELETE FROM file_gc_queue WHERE id=%llu", id);
                    if ((pgres2 = PQexec(pgconn, path)) != NULL)
                        PQclear(pgres2);
-                   ok = TRUE;
+                   ok = true;
                    continue;
                }
            }
@@ -2814,7 +2862,7 @@ skip:
            if ((pgres = PQexec(pgconn, "DELETE FROM file_gc_queue")) != NULL)
                PQclear(pgres);
            else
-               ok = FALSE;
+               ok = false;
        }
        if (ok) {
            if ((pgres = PQexec(pgconn,
@@ -2822,7 +2870,7 @@ skip:
                "'file_gc_queue','id'),1,true)")) != NULL)
                PQclear(pgres);
            else
-               ok = FALSE;
+               ok = false;
        }
        if (ok) {
            if ((pgres = PQexec(pgconn, "COMMIT")) != NULL)
index 6380f4d..e20a2de 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.h,v 1.55 2011/02/08 00:57:00 mmondor Exp $ */
+/* $Id: mmsmtpd.h,v 1.56 2012/07/10 05:07:50 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2008, Matthew Mondor
@@ -68,7 +68,7 @@
 
 /* DEFINITIONS */
 #define DAEMON_NAME    "mmsmtpd"
-#define DAEMON_VERSION "mmmail-0.3.4"
+#define DAEMON_VERSION "mmmail-0.3.5"
 
 /* Negative states are used by the state swapper, others are real states */
 #define STATE_ERROR    -3
@@ -181,6 +181,7 @@ typedef struct rcptnode {
     char address[64], foraddress[64];
     uint64_t hash;
     bool relay;                /* Non-local */
+    bool list;         /* Mailing list */
 } rcptnode;
 
 /* This structure is used to keep a cache of recent hosts from which mail was
@@ -219,7 +220,7 @@ typedef struct command {
 /* Information for a mailbox */
 struct box_info {
     long max_size, size, max_msgs, msgs;
-    bool filter, filter_type;
+    bool filter, filter_type, list;
 };
 
 /* For fast command lookup */
@@ -316,7 +317,7 @@ static void do_data_stats(clientenv *, rcptnode *, size_t);
 static bool address_relay_allow(clientenv *, int *, const char *);
 static void iso_time(char *);
 static bool message_write(char *, const char *, size_t, struct fdbrb_buffer *,
-       const char *);
+       rcptnode *rnode);
 static bool do_data_file(clientenv *, struct fdbrb_buffer *,
                struct validate_udata *);
 static bool do_data_queue_box(clientenv *, const char *, size_t, struct