Hello everyone, This is against the dbmail-1.2 cvs again, and it includes my transaction patch from yesterday.
I noticed that when copying messages over imap from cyrus into dbmail, the message flags were not preserved. This is because ic_append was skipping over the flags as spec'd by the client, and the mysql db_imap_append func was always setting the message to read. dbmail 2.0 seems to do the same (just reading code, haven't tried it). Patch below fixes things for me, postgres is again left as an exercise for the reader, or at least someone who can test the resulting code. -chris
diff -u -r1.41 db.h --- db.h 2003/08/27 09:38:56 1.41 +++ db.h 2003/10/17 15:59:49 @@ -119,6 +119,8 @@ int db_get_nofity_address(u64_t userid, char **notify_address); int db_get_reply_body(u64_t userid, char **body); +int db_start_transaction(void); +int db_stop_transaction(void); u64_t db_get_mailboxid(u64_t useridnr, const char *mailbox); u64_t db_get_useridnr(u64_t messageidnr); u64_t db_get_message_mailboxid(u64_t messageidnr); @@ -158,7 +160,7 @@ u64_t db_deleted_purge(); u64_t db_check_sizelimit (u64_t addblocksize, u64_t messageidnr, u64_t *useridnr); -int db_imap_append_msg(const char *msgdata, u64_t datalen, u64_t mboxid, u64_t uid); +int db_imap_append_msg(const char *msgdata, u64_t datalen, u64_t mboxid, u64_t uid, int *flaglist); /* mailbox functionality */ u64_t db_findmailbox(const char *name, u64_t useridnr); diff -u -r1.110 imapcommands.c --- imapcommands.c 2003/06/11 08:27:46 1.110 +++ imapcommands.c 2003/10/17 15:59:51 @@ -1357,7 +1356,9 @@ imap_userdata_t *ud = (imap_userdata_t*)ci->userData; u64_t mboxid; int i,internal_date_idx=-1,result; + int flaglist[IMAP_NFLAGS]; + memset(flaglist, 0, sizeof(int) * IMAP_NFLAGS); if (!args[0] || !args[1]) { fprintf(ci->tx,"%s BAD invalid arguments specified to APPEND\r\n", tag); @@ -1386,11 +1387,18 @@ /* check if a flag list has been specified */ if (args[i][0] == '(') { + int j; /* ok fetch the flags specified */ trace(TRACE_DEBUG, "ic_append(): flag list found:\n"); while (args[i] && args[i][0] != ')') { + for (j=0; j<IMAP_NFLAGS; j++) + if (strcasecmp(args[i],imap_flag_desc_escaped[j]) == 0) + { + flaglist[j] = 1; + break; + } trace(TRACE_DEBUG, "%s ",args[i]); i++; } @@ -1422,7 +1430,7 @@ /* ok literal msg should be in args[i] */ /* insert this msg */ - result = db_imap_append_msg(args[i], strlen(args[i]), mboxid, ud->userid); + result = db_imap_append_msg(args[i], strlen(args[i]), mboxid, ud->userid, flaglist); switch (result) { case -1: diff -u -r1.95 pipe.c --- pipe.c 2003/03/17 16:04:08 1.95 +++ pipe.c 2003/10/17 15:59:51 @@ -192,6 +192,8 @@ /* get the first target address */ tmp=list_getstart(users); + if (db_start_transaction()) + trace(TRACE_STOP, "insert_messages(): error starting transaction"); while (tmp!=NULL) { /* loops all mailusers and adds them to the list */ @@ -528,6 +530,9 @@ *((u64_t *)tmp->data)); } } + + if (db_stop_transaction()) + trace(TRACE_STOP, "insert_messages(): error ending transaction"); trace (TRACE_DEBUG,"insert_messages(): Freeing memory blocks"); diff -u -r1.75 dbmysql.c --- mysql/dbmysql.c 2003/10/13 11:42:29 1.75 +++ mysql/dbmysql.c 2003/10/17 15:59:53 @@ -123,7 +123,31 @@ return 0; } +int db_start_transaction(void) +{ + snprintf(query, DEF_QUERYSIZE, "BEGIN"); + + if (db_query(query) == -1) + { + /* query failed */ + trace (TRACE_ERROR, "transaction begin failed"); + return -1; + } + return 0; +} +int db_stop_transaction(void) +{ + snprintf(query, DEF_QUERYSIZE, "COMMIT"); + + if (db_query(query) == -1) + { + /* query failed */ + trace (TRACE_ERROR, "transaction commit failed"); + return -1; + } + return 0; +} /* * returns the number of bytes used by user userid or * (u64_t)(-1) on dbase failure @@ -1299,12 +1323,17 @@ u64_t currmail_size = 0, maxmail_size = 0, j, n; *useridnr = db_get_useridnr (message_idnr); - + maxmail_size = auth_getmaxmailsize(*useridnr); + if (maxmail_size == 0) + { + trace (TRACE_INFO,"db_check_sizelimit(): mailboxsize of useridnr %llu is zero, skipping check\n", *useridnr); + return 0; + } + /* checking current size */ snprintf (query, DEF_QUERYSIZE,"SELECT mailbox_idnr FROM mailboxes WHERE owner_idnr = %llu", *useridnr); - if (db_query(query) != 0) { trace (TRACE_ERROR,"db_check_sizelimit(): could not execute query [%s]\n", @@ -1350,17 +1379,10 @@ mysql_free_result(res); - /* current mailsize from INBOX is now known, now check the maxsize for this user */ - maxmail_size = auth_getmaxmailsize(*useridnr); - - trace (TRACE_DEBUG, "db_check_sizelimit(): comparing currsize + blocksize [%llu], " "maxsize [%llu]\n", currmail_size, maxmail_size); - - /* currmail already represents the current size of messages from this user */ - if (((currmail_size) > maxmail_size) && (maxmail_size != 0)) { trace (TRACE_INFO,"db_check_sizelimit(): mailboxsize of useridnr %llu exceed with %llu bytes\n", @@ -2332,7 +2354,7 @@ /* - * db_imap_append_msg() + * __db_imap_append_msg() * * inserts a message * @@ -2343,7 +2365,7 @@ * 2 mail quotum exceeded * */ -int db_imap_append_msg(const char *msgdata, u64_t datalen, u64_t mboxid, u64_t uid) +static int __db_imap_append_msg(const char *msgdata, u64_t datalen, u64_t mboxid, u64_t uid, int *flaglist) { char timestr[30]; time_t td; @@ -2351,17 +2373,18 @@ u64_t msgid,cnt; int result; char unique_id[UID_SIZE]; /* unique id */ + int i; time(&td); /* get time */ tm = *localtime(&td); /* get components */ strftime(timestr, sizeof(timestr), "%G-%m-%d %H:%M:%S", &tm); /* create a msg - * status and seen_flag are set to 001, which means the message has been read + * status is 001 (it gets updated later) */ snprintf(query, DEF_QUERYSIZE, "INSERT INTO messages " - "(mailbox_idnr,messagesize,unique_id,internal_date,status," - " seen_flag) VALUES (%llu, 0, \"\", \"%s\",001,1)", + "(mailbox_idnr,messagesize,unique_id,internal_date,status)" + " VALUES (%llu, 0, \"\", \"%s\",001)", mboxid, timestr); if (db_query(query) == -1) @@ -2506,13 +2529,45 @@ /* create a unique id */ snprintf (unique_id,UID_SIZE,"%lluA%lu",msgid,td); + /* set any flags we were passed */ + for (i = 0 ; i < IMAP_NFLAGS ; i++) + { + if (flaglist[i]) + { + db_set_msgflag(msgid, mboxid, flaglist, IMAPFA_REPLACE); + break; + } + } + /* set info on message */ db_update_message (msgid, unique_id, datalen, 0); - return 0; } +/* + * db_imap_append_msg() + * + * inserts a message + * + * returns: + * -1 serious dbase/memory error + * 0 ok + * 1 invalid msg + * 2 mail quotum exceeded + * + */ +int db_imap_append_msg(const char *msgdata, u64_t datalen, u64_t mboxid, u64_t uid, int *flaglist) +{ + int ret; + if (db_start_transaction()) + return -1; + ret = __db_imap_append_msg(msgdata, datalen, mboxid, uid, flaglist); + if (db_stop_transaction() && ret == 0) + ret = -1; + return ret; +} + /* * db_insert_message_complete() * @@ -3212,7 +3267,7 @@ * copies a msg to a specified mailbox * returns 0 on success, -1 on failure, -2 on quotum exceeded/quotum would exceed */ -int db_copymsg(u64_t msgid, u64_t destmboxid) +static int __db_copymsg(u64_t msgid, u64_t destmboxid) { u64_t newid,tmpid, curr_quotum, userid, maxmail, msgsize; time_t td; @@ -3227,13 +3282,6 @@ return -1; } - curr_quotum = db_get_quotum_used(userid); - if (curr_quotum == -1 || curr_quotum == -2) - { - trace(TRACE_ERROR, "db_copymsg(): error fetching used quotum for user [%llu]", userid); - return -1; - } - maxmail = auth_getmaxmailsize(userid); if (maxmail == -1) { @@ -3243,6 +3291,13 @@ if (maxmail > 0) { + curr_quotum = db_get_quotum_used(userid); + if (curr_quotum == -1 || curr_quotum == -2) + { + trace(TRACE_ERROR, "db_copymsg(): error fetching used quotum for user [%llu]", userid); + return -1; + } + if (curr_quotum >= maxmail) { trace(TRACE_INFO, "db_copymsg(): quotum already exceeded\n"); @@ -3407,6 +3462,22 @@ return 0; /* success */ } +/* + * db_copymsg() + * + * copies a msg to a specified mailbox + * returns 0 on success, -1 on failure, -2 on quotum exceeded/quotum would exceed + */ +int db_copymsg(u64_t msgid, u64_t destmboxid) +{ + int ret; + if (db_start_transaction()) + return -1; + ret = __db_copymsg(msgid, destmboxid); + if (db_stop_transaction() && ret == 0) + ret = -1; + return ret; +} /* * db_getmailboxname() diff -u -r1.103 dbpgsql.c --- pgsql/dbpgsql.c 2003/10/13 11:42:30 1.103 +++ pgsql/dbpgsql.c 2003/10/17 15:59:56 @@ -2149,7 +2149,7 @@ * 2 mail quotum exceeded * */ -int db_imap_append_msg(const char *msgdata, u64_t datalen, u64_t mboxid, u64_t uid) +int db_imap_append_msg(const char *msgdata, u64_t datalen, u64_t mboxid, u64_t uid, int *flaglist) { char timestr[30]; time_t td;