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;