--- dbpgsql.c.orig	Wed Jan 14 16:20:53 2004
+++ dbpgsql.c	Tue Feb  3 19:06:55 2004
@@ -1219,32 +1219,157 @@
    * returns 0 when situation is ok 
    */
 
-  u64_t currmail_size = 0, maxmail_size = 0, j, n;
+  u64_t currmail_size = 0, maxmail_size = 0, j, n, client_idnr, client_maxmail;
 
   *useridnr = db_get_useridnr (messageidnr);
 
+  /* get the user's individual limit */
+  maxmail_size = auth_getmaxmailsize(*useridnr);
+  /* if no limits are set for the both user and client, these calculations are unneccessary */
+  if (maxmail_size > 0)
+    {
     /* checking current size */
-  snprintf (query, DEF_QUERYSIZE,"SELECT mailbox_idnr FROM mailboxes WHERE owner_idnr = %llu::bigint",
+    snprintf (query, DEF_QUERYSIZE,"SELECT mailbox_idnr FROM mailboxes WHERE owner_idnr = %llu::bigint",
             *useridnr);
+  
+    if (db_query(query) != 0)
+      {
+        trace (TRACE_ERROR,"db_check_sizelimit(): could not execute query [%s]\n",
+	       query);
+        return -1;
+      }
+  
+    if (PQntuples(res)<1)
+      {
+        trace (TRACE_ERROR,"db_check_sizelimit(): user has NO mailboxes\n");
+        PQclear(res);
+        return 0;
+      }
+  
+    for (PQcounter = 0; PQcounter < PQntuples (res); PQcounter++)
+      {
+        trace (TRACE_DEBUG,"db_check_sizelimit(): checking mailbox [%s]\n",value);
+        value = PQgetvalue (res, PQcounter, 0);
+  
+        n = value ? strtoull(value, NULL, 10) : 0;
+        j = db_check_mailboxsize(n);
+  
+        if (j == (u64_t)-1)
+          {
+	    trace(TRACE_ERROR,"db_check_sizelimit(): could not verify mailboxsize\n");
+  
+	    PQclear(res);
+	    return -1;
+          }
+  
+        currmail_size += j;
+      }
+  
+    PQclear(res);
+  
+    trace (TRACE_DEBUG, "db_check_sizelimit(): comparing currsize + blocksize  [%llu], maxsize [%llu]\n",
+	   currmail_size, maxmail_size);
+  
+    if ((currmail_size > maxmail_size) && (maxmail_size != 0))
+      {
+        trace (TRACE_INFO,"db_check_sizelimit(): mailboxsize of useridnr %llu exceed with %llu bytes\n", 
+	       *useridnr, (currmail_size)-maxmail_size);
+  
+        /* user is exceeding, we're going to execute a rollback now */
+        /* FIXME: this should be a transaction based roll back in PostgreSQL */
+  
+        snprintf (query,DEF_QUERYSIZE,"DELETE FROM messageblks WHERE message_idnr = %llu::bigint", 
+                messageidnr);
+
+        if (db_query(query) != 0)
+          {
+	    trace (TRACE_ERROR,"db_check_sizelimit(): rollback of mailbox add failed\n");
+	    return -2;
+          }
+  
+        snprintf (query,DEF_QUERYSIZE,"DELETE FROM messages WHERE message_idnr = %llu::bigint",
+                  messageidnr);
+  
+        if (db_query(query) != 0)
+          {
+	    trace (TRACE_ERROR,"db_check_sizelimit(): rollblock of mailbox add failed."
+		   " DB might be inconsistent."
+		   " run dbmail-maintenance\n");
+	    return -2;
+          }
+  
+        return 1;
+    }
+  }
+  else 
+    {
+       trace (TRACE_DEBUG,"user has no individual quota\n");
+    }
+
+  /* see what client group the user is in */
+  snprintf (query, DEF_QUERYSIZE,"SELECT client_idnr FROM users WHERE user_idnr = %llu::bigint",*useridnr);
+  if (db_query(query) == -1)
+    {
+      trace(TRACE_ERROR,"db_check_sizelimit(): could not retrieve client_idnr from users: %s", query);
+      return -1;
+    }
+  if (PQntuples(res) == 0)
+    {
+      trace(TRACE_WARNING, "db_check_sizelimit(): user [%llu] does not have any client_idnr set", *useridnr);
+      PQclear(res);
+      return 0;
+    }
+  else 
+    client_idnr = strtoull(PQgetvalue (res, 0, 0), NULL, 10);
+  PQclear(res);
+
+  /* now look for a client group maxmail */
+  snprintf (query, DEF_QUERYSIZE,"SELECT value FROM config WHERE item = 'client_maxmail_%llu'",client_idnr);
+  if (db_query(query) == -1)
+    {
+      trace(TRACE_ERROR,"db_check_sizelimit(): could not retrieve client maxmail from config: %s", query);
+      return -1;
+    }
+  if (PQntuples(res) == 0)
+    {
+      PQclear(res);
+      return 0;
+    }
+  else 
+    {
+    /* as there are no unique constaints on config table, 
+       if there were multiple rows returned, we're just going to use the first row found */
+    client_maxmail = strtoull(PQgetvalue (res, 0, 0), NULL, 10);
+    }
 
+  PQclear(res);
 
+  trace (TRACE_DEBUG, "db_check_sizelimit(): maxmail for client_idnr [%llu] is [%llu]\n",client_idnr,client_maxmail);
+  if (client_maxmail == 0) 
+    return 0;
+
+  /* retrieve list of all mailboxes belonging to users in the group 
+     if we already checked the user's individual usage, we can exclude his mailboxes from the list */
+  if (maxmail_size==0) 
+      snprintf (query, DEF_QUERYSIZE,"SELECT m.mailbox_idnr FROM mailboxes m,users u WHERE m.owner_idnr=u.user_idnr AND u.client_idnr = %llu::bigint",client_idnr);
+  else 
+      snprintf (query, DEF_QUERYSIZE,"SELECT m.mailbox_idnr FROM mailboxes m,users u WHERE m.owner_idnr=u.user_idnr AND u.client_idnr = %llu::bigint AND u.user_idnr != %llu::bigint",client_idnr,*useridnr);
+            
   if (db_query(query) != 0)
     {
       trace (TRACE_ERROR,"db_check_sizelimit(): could not execute query [%s]\n",
 	     query);
       return -1;
     }
-
   if (PQntuples(res)<1)
     {
-      trace (TRACE_ERROR,"db_check_sizelimit(): user has NO mailboxes\n");
       PQclear(res);
       return 0;
     }
 
   for (PQcounter = 0; PQcounter < PQntuples (res); PQcounter++)
     {
-      trace (TRACE_DEBUG,"db_check_sizelimit(): checking mailbox [%s]\n",value);
+      /* now check the size of each mailbox */
       value = PQgetvalue (res, PQcounter, 0);
 
       n = value ? strtoull(value, NULL, 10) : 0;
@@ -1257,28 +1382,23 @@
 	  PQclear(res);
 	  return -1;
         }
-
       currmail_size += j;
     }
 
   PQclear(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))
+  /* 
+     finally, check if the current message pushes us over the group limit.
+  */
+
+  trace (TRACE_DEBUG, "db_check_sizelimit(): comparing currsize + blocksize  [%llu], client_maxmail [%llu]\n",
+	 currmail_size, client_maxmail);
+  if (currmail_size > client_maxmail)
     {
-      trace (TRACE_INFO,"db_check_sizelimit(): mailboxsize of useridnr %llu exceed with %llu bytes\n", 
-	     *useridnr, (currmail_size)-maxmail_size);
+      trace (TRACE_INFO,"db_check_sizelimit(): combined mailboxsize of clientidnr %llu exceeded by %llu bytes\n", 
+	     client_idnr, currmail_size-client_maxmail);
 
-      /* user is exceeding, we're going to execute a rollback now */
+      /* client is exceeding, we're going to execute a rollback now */
       /* FIXME: this should be a transaction based roll back in PostgreSQL */
 
       snprintf (query,DEF_QUERYSIZE,"DELETE FROM messageblks WHERE message_idnr = %llu::bigint", 
@@ -1303,7 +1423,6 @@
 
       return 1;
     }
-
   return 0;
 }
 
