I've spend a few hours testing dbmail and it looks very good.

I decided to go with what was in CVS. I did a diff of CVS and the 1.1 version and most of the changes looked safe.

Anyhow, I did find one bug that I've attached as a patch against the current CVS state (but I would suggest that someone who knows better ought to review it).

I also have some suggestions for "features" or "fixes".

a) This one is serious because emails are dropped silently. If "dbmail-smtp -m BOX" is used and BOX does not exist, then the email is silently dropped on the floor.

b) If an account exists but the mailbox does not, there should be a way of creating one on demand. For example, if I create an alias like:

test_dbmail: "| /usr/local/sbin/dbmail-smtp -m test_dbmail -u gianni"

If the mailbox "test_dbmail" in account "gianni" does not exist, (before the patch it would silently fail) it will abort. I suggest that another command line option "-c" for "Create mailbox on demand" would be good.


c) If the postgresql database goes down, imapd does not recover when the database comes back and requires a re-start of dbmail-imapd. It would be nice if dbmail-imapd recovered from database re-starts.

d) imaps (imap over SSL) would really be nice.

e) passwords should not be logged .... this is far more serious than you first think.

Jun 28 08:10:08 uluru dbmail/smtp[23610]: GetConfigValue(): searching value for config item [pass] Jun 28 08:10:08 uluru dbmail/smtp[23610]: GetConfigValue(): found value [secretpassword]

f) scrubbing the database really need a cron job ? (reminds me - I need to check to see if it the
dbmail-maintenance does a VACUUM;).

g) There should be an config value to use a different port for connecting to postgresql. I like to run different version of postgresql on the same machine and I place them on different ports. Currently dbmail only has "host" "db" "user" and "pass" parameters.


Other Notes:

Most of the issues I have a nit-picks and I'm sure will get resolved in good time.

I tested emails with large (20MB) attachments, these seemed to work ok. Actually better than OK. Performance was good and using a database meant that the contention issues with the malbox caused no slow down whatsoever doing other transactions. The performance seemed to be disk bound. (I have the mail spool and the database directory on the same machine) I could also be dead wrong on this one but I was not concerned from a performance standpoint.

I finally grepped the source and I noticed that dbmail is licenced with GPL+ (+ being for gimme bradding rights ammo). It would be good to mention the whole GPL thing on the web site. I didn't want to use it if the licence was not "open source".

As for bragging rights, it's not much ammo. I run email services off my own server and I set up email accounts for friends and family. I ran into the issue where the default RedHat imapd (I think it's WU-Imapd) was running away and causing a whole bunch of issues and very sluggish service. I also have a requirement where I need to have multiple InBox's in various accounts.

My conclusion is that I am going to use dbmail over other imap solutions because
   a) it's simpler than most other solutions.
b) the design. The database solves the contention issues, maildirs are good but databases are better.
   c) I like postgresql.

I'm now looking for some migration tools, any suggestions welcome. I would like a few command line tools to mess with imap servers, create mailboxes, transfer emails between boxes etc.

Finally, thanks to everyone who helped make dbmail what it is. It's great to see such a good product under the GPL.

BTW - any pointers for a newbie are most welcome.

Regards
G

Index: db.h
===================================================================
RCS file: /cvsroot-dbmail/dbmail/db.h,v
retrieving revision 1.38
diff -a -u -r1.38 db.h
--- db.h        2003/03/17 16:04:08     1.38
+++ db.h        2003/06/28 17:28:40
@@ -120,7 +120,7 @@
 int db_get_reply_body(u64_t userid, char **body);
 
 u64_t db_get_mailboxid(u64_t useridnr, const char *mailbox);
-u64_t db_get_useridnr(u64_t messageidnr);
+u64_t db_get_useridnr(u64_t messageidnr, int *tuples);
 u64_t db_get_message_mailboxid(u64_t messageidnr);
 u64_t db_insert_message(u64_t useridnr, const char *deliver_to_mailbox, const 
char *uniqueid);
 u64_t db_update_message(u64_t messageidnr, const char *unique_id,
Index: pipe.c
===================================================================
RCS file: /cvsroot-dbmail/dbmail/pipe.c,v
retrieving revision 1.95
diff -a -u -r1.95 pipe.c
--- pipe.c      2003/03/17 16:04:08     1.95
+++ pipe.c      2003/06/28 17:28:40
@@ -412,7 +412,7 @@
                                      &bounce_userid))
            {
            case 1:
-             trace (TRACE_DEBUG,"insert_messages(): message NOT inserted. 
Maxmail exceeded");
+             trace (TRACE_DEBUG,"insert_messages(): message NOT inserted. 
Maxmail exceeded OR mailbox does not exist");
              bounce_id = auth_get_userid(&bounce_userid);
              bounce (header, headersize, bounce_id, 
BOUNCE_STORAGE_LIMIT_REACHED);
              my_free (bounce_id);
Index: pgsql/dbpgsql.c
===================================================================
RCS file: /cvsroot-dbmail/dbmail/pgsql/dbpgsql.c,v
retrieving revision 1.100
diff -a -u -r1.100 dbpgsql.c
--- pgsql/dbpgsql.c     2003/05/26 07:22:22     1.100
+++ pgsql/dbpgsql.c     2003/06/28 17:28:43
@@ -529,18 +529,29 @@
 /* 
  * returns the userid from a messageidnr 
  */
-u64_t db_get_useridnr (u64_t messageidnr)
+u64_t db_get_useridnr (u64_t messageidnr, int * tuples)
 {
   u64_t userid;
 
+  int l_tuples;
+
   snprintf (query, DEF_QUERYSIZE, "SELECT owner_idnr FROM mailboxes WHERE 
mailbox_idnr = "
            "(SELECT mailbox_idnr FROM messages WHERE message_idnr = 
%llu::bigint)",
             messageidnr);
 
   if (db_query(query)==-1)
-    return 0;
+  {
+    trace(TRACE_STOP, "db_get_useridnr(): dbquery failed");
+  }    
 
-  if (PQntuples(res)<1) 
+  l_tuples = PQntuples(res);
+
+  if ( tuples )
+    {
+      * tuples = l_tuples;
+    }
+               
+  if (l_tuples<1) 
     {
       trace (TRACE_DEBUG,"db_get_useridnr(): this is not right!");
       PQclear(res);
@@ -1198,7 +1209,7 @@
 
   u64_t currmail_size = 0, maxmail_size = 0, j, n;
 
-  *useridnr = db_get_useridnr (messageidnr);
+  *useridnr = db_get_useridnr (messageidnr, 0);
 
     /* checking current size */
   snprintf (query, DEF_QUERYSIZE,"SELECT mailbox_idnr FROM mailboxes WHERE 
owner_idnr = %llu::bigint",
@@ -1216,7 +1227,7 @@
     {
       trace (TRACE_ERROR,"db_check_sizelimit(): user has NO mailboxes\n");
       PQclear(res);
-      return 0;
+      return 1;
     }
 
   for (PQcounter = 0; PQcounter < PQntuples (res); PQcounter++)
@@ -2162,6 +2173,7 @@
   msgid = db_insert_result("message_idnr");
 
   result = db_check_sizelimit(datalen, msgid, &uid);
+
   if (result == -1 || result == -2)
     {     
       trace(TRACE_ERROR, "db_imap_append_msg(): dbase error checking size 
limit\n");
@@ -3087,11 +3099,13 @@
   u64_t newmsgid, curr_quotum, userid, maxmail, msgsize;
   time_t td;
 
+  int l_tuples;
+
   time(&td);              /* get time */
 
   /* check if there is space left for this message */
-  userid = db_get_useridnr(msgid);
-  if (userid == -1)
+  userid = db_get_useridnr(msgid, &l_tuples);
+  if ( (userid == -1) && (l_tuples > 0) )
     {
       trace(TRACE_ERROR, "db_copymsg(): error fetching userid");
       return -1;

Reply via email to