Aaron Stone wrote:
On Wed, Mar 9, 2005, Paul J Stevens <[EMAIL PROTECTED]> said:


I've also committed this to the 2.0 svn branch. About time we cut a
2.0.4rc1 I suppose. Aaron?  We can defer bug #161 to 2.0.5 or even 2.1,
but any guesstimates on #164, perhaps?


Ok, thanks for reminding me. Let's kick #161 because if we haven't started
looking into what crashes the mime parser, now ain't the time. For #164, I
will *right now* put my work-in-progress patch on the bug page. Paul, I
hope you can run with it and get 2.0.4 out the door!

I got it to compile, but I'll have to think a bit about the logic involved here.




--
  ________________________________________________________________
  Paul Stevens                                         [EMAIL PROTECTED]
  NET FACILITIES GROUP                     GPG/PGP: 1024D/11F8CD31
  The Netherlands_______________________________________www.nfg.nl
#! /bin/sh /usr/share/dpatch/dpatch-run
## 01_quota.dpatch by  <[EMAIL PROTECTED]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.

@DPATCH@
diff -urNad dbmail-2.0/dsn.c /tmp/dpep.9YzUej/dbmail-2.0/dsn.c
--- dbmail-2.0/dsn.c    2005-03-10 14:43:49.000000000 +0100
+++ /tmp/dpep.9YzUej/dbmail-2.0/dsn.c   2005-03-10 14:44:46.000000000 +0100
@@ -407,10 +407,12 @@
        list_freelist(&deliveries->start);
 }
 
-dsn_class_t dsnuser_worstcase_int(int has_2, int has_4, int has_5)
+delivery_status_t dsnuser_worstcase_int(int has_2, int has_4, int has_5, int 
has_5_2)
 {
        dsn_class_t exitcode;
 
+       /**/
+
        /* If only one code, use it. */
        if (has_2 && !has_4 && !has_5)  /* Only 2 */
                exitcode = DSN_CLASS_OK;
@@ -432,15 +434,17 @@
        return exitcode;
 }
 
-dsn_class_t dsnuser_worstcase_list(struct list * deliveries)
+delivery_status_t dsnuser_worstcase_list(struct list * deliveries)
 {
+       dsn_t dsn;
        struct element *tmp;
-       int has_2 = 0, has_4 = 0, has_5 = 0;
+       int has_2 = 0, has_4 = 0, has_5 = 0, has_5_2 = 0;
 
        /* Get one reasonable error code for everyone. */
        for (tmp = list_getstart(deliveries); tmp != NULL;
             tmp = tmp->nextnode) {
-               switch (((deliver_to_user_t *) tmp->data)->dsn.class) {
+               delivery_status_t dsn = ((deliver_to_user_t *) tmp->data)->dsn;
+               switch (dsn.class) {
                case DSN_CLASS_OK:
                        /* Success. */
                        has_2 = 1;
@@ -451,7 +455,10 @@
                        break;
                case DSN_CLASS_FAIL:
                        /* Permanent failure. */
-                       has_5 = 1;
+                       if (dsn.subject == 2)
+                               has_5_2 = 1;
+                       else
+                               has_5 = 1;
                        break;
                case DSN_CLASS_NONE:
                        /* Nothing doing. */
@@ -461,5 +468,5 @@
 
        /* If we never made it into the list, all zeroes will
         * yield a temporary failure, which is pretty reasonable. */
-       return dsnuser_worstcase_int(has_2, has_4, has_5);
+       return dsnuser_worstcase_int(has_2, has_4, has_5, has_5_2);
 }
diff -urNad dbmail-2.0/main.c /tmp/dpep.9YzUej/dbmail-2.0/main.c
--- dbmail-2.0/main.c   2005-03-10 14:43:52.000000000 +0100
+++ /tmp/dpep.9YzUej/dbmail-2.0/main.c  2005-03-10 14:44:46.000000000 +0100
@@ -466,8 +466,12 @@
        /* If there wasn't already an EX_TEMPFAIL from insert_messages(),
         * then see if one of the status flags was marked with an error. */
        if (!exitcode) {
+               delivery_status_t final_dsn;
+
                /* Get one reasonable error code for everyone. */
-               switch (dsnuser_worstcase_list(&dsnusers)) {
+               final_dsn = dsnuser_worstcase_list(&dsnusers);
+
+               switch (final_dsn.class) {
                case DSN_CLASS_OK:
                        exitcode = EX_OK;
                        break;
@@ -476,7 +480,12 @@
                        break;
                case DSN_CLASS_NONE:
                case DSN_CLASS_FAIL:
-                       exitcode = EX_NOUSER;
+                       /* If we're over-quota, say that,
+                        * else it's a generic user error. */
+                       if (final_dsn.subject = 2)
+                               exitcode = EX_CANTCREAT;
+                       else
+                               exitcode = EX_NOUSER;
                        break;
                }
        }
diff -urNad dbmail-2.0/pipe.c /tmp/dpep.9YzUej/dbmail-2.0/pipe.c
--- dbmail-2.0/pipe.c   2005-03-10 14:43:49.000000000 +0100
+++ /tmp/dpep.9YzUej/dbmail-2.0/pipe.c  2005-03-10 14:44:46.000000000 +0100
@@ -554,7 +554,7 @@
        for (element = list_getstart(dsnusers); element != NULL;
             element = element->nextnode) {
                struct element *userid_elem;
-               int has_2 = 0, has_4 = 0, has_5 = 0;
+               int has_2 = 0, has_4 = 0, has_5 = 0, has_5_2 = 0;
                deliver_to_user_t *delivery =
                    (deliver_to_user_t *) element->data;
 
@@ -578,22 +578,28 @@
                                                 msgsize, rfcsize,
                                                 useridnr,
                                                 delivery->mailbox)) {
-                       case DSN_CLASS_OK:
+                       case SORT_SUCCESS:
                                /* Indicate success. */
                                trace(TRACE_DEBUG,
                                      "%s, %s: successful sort_and_deliver for 
useridnr [%llu]",
                                      __FILE__, __func__, useridnr);
                                has_2 = 1;
                                break;
-                       case DSN_CLASS_FAIL:
+                       case SORT_FAILURE:
                                /* Indicate permanent failure. */
                                trace(TRACE_ERROR,
                                      "%s, %s: permanent failure 
sort_and_deliver for useridnr [%llu]",
                                      __FILE__, __func__, useridnr);
                                has_5 = 1;
                                break;
-                       case DSN_CLASS_TEMP:
-                       case -1:
+                       case SORT_OVER_QUOTA:
+                               /* Indicate over quota. */
+                               trace(TRACE_ERROR,
+                                     "%s, %s: temporary failure 
sort_and_deliver for useridnr [%llu]",
+                                     __FILE__, __func__, useridnr);
+                               has_5_2 = 1;
+                               break;
+                       case SORT_WEIRD_ERROR:
                        default:
                                /* Assume a temporary failure */
                                trace(TRACE_ERROR,
@@ -610,7 +616,7 @@
                                      __FILE__, __func__);
                }               /* from: the useridnr for loop */
 
-               switch (dsnuser_worstcase_int(has_2, has_4, has_5)) {
+               switch (dsnuser_worstcase_int(has_2, has_4, has_5, has_5_2)) {
                case DSN_CLASS_OK:
                        delivery->dsn.class = DSN_CLASS_OK;     /* Success. */
                        delivery->dsn.subject = 1;      /* Address related. */
@@ -634,6 +640,11 @@
                        delivery->dsn.subject = 1;      /* Address related. */
                        delivery->dsn.detail = 1;       /* Does not exist. */
                        break;
+               case DSN_CLASS_QUOTA:
+                       delivery->dsn.class = DSN_CLASS_FAIL;   /* Permanent 
failure. */
+                       delivery->dsn.subject = 2;      /* Mailbox related. */
+                       delivery->dsn.detail = 2;       /* Over quota limit. */
+                       break;
                case DSN_CLASS_NONE:
                        /* Leave the DSN status at whatever dsnuser_resolve set 
it at. */
                        break;
diff -urNad dbmail-2.0/sort/sort.c /tmp/dpep.9YzUej/dbmail-2.0/sort/sort.c
--- dbmail-2.0/sort/sort.c      2005-03-10 14:43:52.000000000 +0100
+++ /tmp/dpep.9YzUej/dbmail-2.0/sort/sort.c     2005-03-10 14:44:46.000000000 
+0100
@@ -111,267 +111,39 @@
        if (mailbox == NULL)
                mailbox = inbox;
 
-       /* actions is a list of things to do with this message
-        * each data pointer in the actions list references
-        * a structure like this:
-        *
-        * typedef sort_action {
-        *   int method,
-        *   char *destination,
-        *   char *message
-        * } sort_action_t;
-        * 
-        * Where message is some descriptive text, used
-        * primarily for rejection noticed, and where
-        * destination is either a mailbox name or a 
-        * forwarding address, and method is one of these:
-        *
-        * SA_KEEP,
-        * SA_DISCARD,
-        * SA_REDIRECT,
-        * SA_REJECT,
-        * SA_FILEINTO
-        * (see RFC 3028 [SIEVE] for details)
-        *
-        * SA_SIEVE:
-        * In addition, this implementation allows for 
-        * the internel Regex matching to call a Sieve
-        * script into action. In this case, the method
-        * is SA_SIEVE and the destination is the script's name.
-        * Note that Sieve must be enabled in the configuration
-        * file or else an error will be generated.
-        *
-        * In the absence of any valid actions (ie. actions
-        * is an empty list, or all attempts at performing the
-        * actions fail...) an implicit SA_KEEP is performed,
-        * using INBOX as the destination (hardcoded).
-        * */
-
-       if (list_totalnodes(&actions) > 0) {
-               tmp = list_getstart(&actions);
-               while (tmp != NULL) {
-                       /* Try not to think about the structures too hard ;-) */
-                       switch ((int) ((sort_action_t *) tmp->data)->
-                               method) {
-                       case SA_SIEVE:
-                               {
-                                       /* Run the script specified by 
destination and
-                                        * add the resulting list onto the 
*end* of the
-                                        * actions list. Note that this is a 
deep hack...
-                                        * */
-                                       if ((char *) ((sort_action_t *)
-                                                     tmp->data)->
-                                           destination != NULL) {
-                                               struct list localtmplist;
-                                               struct element
-                                                   *localtmpelem;
-//                      if (sortsieve_msgsort(useridnr, header, headersize, 
(char *)((sort_action_t *)tmp->data)->destination, localtmplist))
-                                               {
-                                                       /* FIXME: This can all 
be replaced with some
-                                                        * function called 
list_append(), if written! */
-                                                       /* Fast forward to the 
end of the actions list */
-                                                       localtmpelem =
-                                                           list_getstart
-                                                           (&actions);
-                                                       while (localtmpelem
-                                                              != NULL) {
-                                                               localtmpelem
-                                                                   =
-                                                                   
localtmpelem->
-                                                                   nextnode;
-                                                       }
-                                                       /* And tack on the 
start of the Sieve list */
-                                                       localtmpelem->
-                                                           nextnode =
-                                                           list_getstart
-                                                           (&localtmplist);
-                                                       /* Remeber to increment 
the node count, too */
-                                                       actions.
-                                                           total_nodes +=
-                                                           list_totalnodes
-                                                           (&localtmplist);
-                                               }
-                                       }
-                                       break;
-                               }
-                       case SA_FILEINTO:
-                               {
-                                       char *fileinto_mailbox =
-                                           (char *) ((sort_action_t *)
-                                                     tmp->data)->
-                                           destination;
-
-                                       /* If the action doesn't come with a 
mailbox, use the default. */
-
-                                       if (fileinto_mailbox == NULL) {
-                                               /* Cast the const away because 
fileinto_mailbox may need to be freed. */
-                                               fileinto_mailbox =
-                                                   (char *) mailbox;
-                                               trace(TRACE_MESSAGE,
-                                                     "sort_and_deliver(): 
mailbox not specified, using [%s]",
-                                                     fileinto_mailbox);
-                                       }
-
-
-                                       /* Did we fail to create the mailbox? */
-                                       if (db_find_create_mailbox
-                                           (fileinto_mailbox, useridnr,
-                                            &mboxidnr) != 0) {
-                                               /* FIXME: Serious failure 
situation! This needs to be
-                                                * passed up the chain to 
notify the user, sender, etc.
-                                                * Perhaps we should *force* 
the implicit-keep to occur,
-                                                * or give another try at using 
INBOX. */
-                                               trace(TRACE_ERROR,
-                                                     "sort_and_deliver(): 
mailbox [%s] not found nor created, message may not have been delivered",
-                                                     fileinto_mailbox);
-                                       } else {
-                                               switch (db_copymsg
-                                                       (msgidnr, mboxidnr,
-                                                        useridnr,
-                                                        &newmsgidnr)) {
-                                               case -2:
-                                                       /* Couldn't deliver 
because the quota has been reached */
-                                                       break;
-                                               case -1:
-                                                       /* Couldn't deliver 
because something something went wrong */
-                                                       trace(TRACE_ERROR,
-                                                             
"sort_and_deliver(): error copying message to user [%llu]",
-                                                             useridnr);
-                                                       /* Don't worry about 
error conditions.
-                                                        * It's annoying if the 
message isn't delivered,
-                                                        * but as long as 
*something* happens it's OK.
-                                                        * Otherwise, 
actiontaken will be 0 and another
-                                                        * delivery attempt 
will be made before passing
-                                                        * up the error at the 
end of the function.
-                                                        * */
-                                                       break;
-                                               default:
-                                                       trace
-                                                           (TRACE_MESSAGE,
-                                                            
"sort_and_deliver(): message id=%llu, size=%llu is inserted",
-                                                            newmsgidnr,
-                                                            totalmsgsize);
-
-                                                       /* Create a unique ID 
for this message;
-                                                        * Each message for 
each user must have a unique ID! 
-                                                        * */
-                                                       create_unique_id
-                                                           (unique_id,
-                                                            newmsgidnr);
-                                                       db_message_set_unique_id
-                                                           (newmsgidnr,
-                                                            unique_id);
-
-                                                       actiontaken = 1;
-                                                       break;
-                                               }
-                                       }
-
-                                       /* If these are not same pointers, then 
we need to free. */
-                                       if (fileinto_mailbox != mailbox)
-                                               dm_free(fileinto_mailbox);
-
-                                       break;
-                               }
-                       case SA_DISCARD:
-                               {
-                                       /* Basically do nothing! */
-                                       actiontaken = 1;
-                                       break;
-                               }
-                       case SA_REJECT:
-                               {
-                                       // FIXME: I'm happy with this code, but 
it's not quite right...
-                                       // Plus we want to specify a message to 
go along with it!
-                                       actiontaken = 1;
-                                       break;
-                               }
-                       case SA_REDIRECT:
-                               {
-                                       char *forward_id;
-                                       struct list targets;
-
-                                       list_init(&targets);
-                                       list_nodeadd(&targets,
-                                                    (char
-                                                     *) ((sort_action_t *)
-                                                         tmp->data)->
-                                                    destination,
-                                                    strlen((char
-                                                            *) ((sort_action_t 
*) tmp->data)->destination) + 1);
-                                       dm_free((char *) ((sort_action_t *)
-                                                         tmp->data)->
-                                               destination);
-
-                                       /* Put the destination into the targets 
list */
-                                       /* The From header will contain... */
-                                       forward_id =
-                                           auth_get_userid(useridnr);
-                                       forward(msgidnr, &targets,
-                                               forward_id, header,
-                                               headersize);
-
-                                       list_freelist(&targets.start);
-                                       dm_free(forward_id);
-                                       actiontaken = 1;
-                                       break;
-                               }
-                               /*
-                                  case SA_KEEP:
-                                  default:
-                                  {
-                                  // Don't worry! This is handled by implicit 
keep :-)
-                                  break;
-                                  }
-                                */
-                       }       /* case */
-                       tmp = tmp->nextnode;
-               }               /* while */
-               list_freelist(&actions.start);
-       } /* if */
-       else {
-               /* Might as well be explicit about this... */
-               actiontaken = 0;
-       }
+       /* There used to be code that handled the result
+        * actions of a Sieve script. Since it wasn't being
+        * used as of DBMail 2.0.3, I pulled it out.
+        * Aaron Stone, 21 Jan 2005. */
 
-       /* This is that implicit keep I mentioned earlier...
-        * If possible, put the message in the specified
-        * mailbox, otherwise use INBOX. */
-       if (actiontaken == 0) {
-               /* Did we fail to create the mailbox? */
-               if (db_find_create_mailbox(mailbox, useridnr, &mboxidnr) !=
-                   0) {
-                       /* Serious failure situation! */
+       /* Did we fail to create the mailbox? */
+       if (db_find_create_mailbox(mailbox, useridnr, &mboxidnr) != 0) {
+               /* Serious failure situation! */
+               trace(TRACE_ERROR,
+                     "sort_and_deliver(): INBOX not found and could not be 
created.");
+               return SORT_FAILURE;
+       } else {
+               switch (db_copymsg(msgidnr, mboxidnr,
+                                  useridnr, &newmsgidnr)) {
+               case -2:
+                       /* Couldn't deliver because the quotum is exceeded. */
+                       trace(TRACE_MESSAGE,
+                             "%s, %s: error copying message to user [%llu], 
maxmail exceeded",
+                             __FILE__, __func__, useridnr);
+                       return SORT_OVER_QUOTA;
+               case -1:
+                       /* Couldn't deliver because something something went 
wrong. */
                        trace(TRACE_ERROR,
-                             "sort_and_deliver(): INBOX not found");
-               } else {
-                       switch (db_copymsg
-                               (msgidnr, mboxidnr, useridnr,
-                                &newmsgidnr)) {
-                       case -2:
-                               /* Couldn't deliver because the quotum is 
exceeded. */
-                               trace(TRACE_DEBUG,
-                                     "%s, %s: error copying message to user 
[%llu], maxmail exceeded",
-                                     __FILE__, __func__, useridnr);
-                               break;
-                       case -1:
-                               /* Couldn't deliver because something something 
went wrong. */
-                               trace(TRACE_ERROR,
-                                     "%s, %s: error copying message to user 
[%llu]",
-                                     __FILE__, __func__, useridnr);
-                               break;
-                       default:
-                               trace(TRACE_MESSAGE,
-                                     "%s, %s: message id=%llu, size=%llu is 
inserted",
-                                     __FILE__, __func__, newmsgidnr,
-                                     totalmsgsize);
-                               actiontaken = 1;
-                               break;
-                       }
+                             "%s, %s: error copying message to user [%llu]",
+                             __FILE__, __func__, useridnr);
+                       return SORT_WEIRD_ERROR;
+               default:
+                       trace(TRACE_MESSAGE,
+                             "%s, %s: message id=%llu, size=%llu is inserted",
+                             __FILE__, __func__, newmsgidnr,
+                             totalmsgsize);
+                       return SORT_SUCCESS;
                }
        }
-
-       if (actiontaken)
-               return DSN_CLASS_OK;
-       return DSN_CLASS_TEMP;
 }
+
diff -urNad dbmail-2.0/sort.h /tmp/dpep.9YzUej/dbmail-2.0/sort.h
--- dbmail-2.0/sort.h   2005-03-10 14:43:49.000000000 +0100
+++ /tmp/dpep.9YzUej/dbmail-2.0/sort.h  2005-03-10 14:44:46.000000000 +0100
@@ -39,7 +39,6 @@
 #define SA_REDIRECT    3
 #define SA_REJECT      4
 #define SA_FILEINTO    5
-#define SA_SIEVE       6
 
 typedef struct sort_action {
        int method;
@@ -47,7 +46,14 @@
        char *message;
 } sort_action_t;
 
-dsn_class_t sort_and_deliver(u64_t msgidnr,
+typedef enum {
+       SORT_SUCCESS = 0,
+       SORT_OVER_QUOTA,
+       SORT_WEIRD_ERROR,
+       SORT_FAILURE
+} sort_result_t;
+
+sort_result_t sort_and_deliver(u64_t msgidnr,
                             const char *header, u64_t headersize,
                             u64_t msgsize, u64_t rfcsize,
                             u64_t useridnr, const char *mailbox);

Reply via email to