--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src.warn-filecount Wed Jun 08 23:33:22 2011 +0200
@@ -0,0 +1,252 @@
+# HG changeset patch
+# Parent 8d6f7028bb88356841de22bf3dd6190d20537ce3
+
+diff -r 8d6f7028bb88 doc/spec.txt
+--- a/doc/spec.txt Thu Jun 02 23:26:40 2011 +0200
++++ b/doc/spec.txt Wed Jun 08 23:30:53 2011 +0200
+@@ -18932,7 +18932,7 @@
+ changed by setting quota_is_inclusive false. When this is done, the check for
+ exceeding the quota does not include the current message. Thus, deliveries
+ continue until the quota has been exceeded; thereafter, no further messages are
+-delivered. See also quota_warn_threshold.
++delivered. See also quota_warn_threshold and quota_filecount_warn_threshold.
+
+ +---------------+---------------+-------------+--------------+
+ |quota_directory|Use: appendfile|Type: string*|Default: unset|
+@@ -18995,14 +18995,15 @@
+ +------------------+---------------+-------------+------------------+
+
+ See below for the use of this option. If it is not set when
+-quota_warn_threshold is set, it defaults to
++quota_warn_threshold or quota_filecount_warn_threshold is set,
++it defaults to
+
+ quota_warn_message = "\
+ To: $local_part@$domain\n\
+ Subject: Your mailbox\n\n\
+ This message is automatically created \
+ by mail delivery software.\n\n\
+- The size of your mailbox has exceeded \
++ The size or filecount of your mailbox has exceeded \
+ a warning threshold that is\n\
+ set by the system administrator.\n"
+
+@@ -19037,6 +19038,14 @@
+ independent of one another except when the threshold is specified as a
+ percentage.
+
+++------------------------------+---------------+-------------+----------+
++|quota_filecount_warn_threshold|Use: appendfile|Type: string*|Default: 0|
+++------------------------------+---------------+-------------+----------+
++
++See quota_warn_threshold. The only difference is that the
++quota_filecount_warn_threshold applies to the number of messages and not to the
++size of the mailbox.
++
+ +---------+---------------+-------------+--------------+
+ |use_bsmtp|Use: appendfile|Type: boolean|Default: false|
+ +---------+---------------+-------------+--------------+
+diff -r 8d6f7028bb88 src/transports/appendfile.c
+--- a/src/transports/appendfile.c Thu Jun 02 23:26:40 2011 +0200
++++ b/src/transports/appendfile.c Wed Jun 08 23:30:53 2011 +0200
+@@ -29,8 +29,17 @@
+ /* Check warn threshold only if quota size set or not a percentage threshold
+ percentage check should only be done if quota > 0 */
+
+-#define THRESHOLD_CHECK (ob->quota_warn_threshold_value > 0 && \
+- (!ob->quota_warn_threshold_is_percent || ob->quota_value > 0))
++#define _THRESHOLD_CHECK(threshold, is_percent, quota) (threshold > 0 && (!is_percent || quota > 0))
++
++#define THRESHOLD_CHECK1 _THRESHOLD_CHECK(ob->quota_warn_threshold_value, \
++ ob->quota_warn_threshold_is_percent, \
++ ob->quota_value)
++
++#define THRESHOLD_CHECK2 _THRESHOLD_CHECK(ob->quota_filecount_warn_threshold_value, \
++ ob->quota_filecount_warn_threshold_is_percent, \
++ ob->quota_filecount_value)
++
++#define THRESHOLD_CHECK (THRESHOLD_CHECK1 || THRESHOLD_CHECK2)
+
+
+ /* Options specific to the appendfile transport. They must be in alphabetic
+@@ -145,6 +154,8 @@
+ (void *)offsetof(appendfile_transport_options_block, quota_directory) },
+ { "quota_filecount", opt_stringptr,
+ (void *)offsetof(appendfile_transport_options_block, quota_filecount) },
++ { "quota_filecount_warn_threshold", opt_stringptr,
++ (void *)offsetof(appendfile_transport_options_block, quota_filecount_warn_threshold) },
+ { "quota_is_inclusive", opt_bool,
+ (void *)offsetof(appendfile_transport_options_block, quota_is_inclusive) },
+ { "quota_size_regex", opt_stringptr,
+@@ -189,6 +200,7 @@
+ NULL, /* quota_filecount */
+ NULL, /* quota_size_regex */
+ NULL, /* quota_warn_threshold */
++ NULL, /* quota_filecount_warn_threshold */
+ NULL, /* mailbox_size_string */
+ NULL, /* mailbox_filecount_string */
+ NULL, /* expand_maildir_use_size_file */
+@@ -206,6 +218,7 @@
+ -1, /* mailbox_size_value */
+ -1, /* mailbox_filecount_value */
+ 0, /* quota_filecount_value */
++ 0, /* quota_filecount_warn_threshold_value */
+ APPENDFILE_MODE, /* mode */
+ APPENDFILE_DIRECTORY_MODE, /* dirmode */
+ APPENDFILE_LOCKFILE_MODE, /* lockfile_mode */
+@@ -240,6 +253,7 @@
+ FALSE, /* mailstore_format */
+ FALSE, /* mbx_format */
+ FALSE, /* quota_warn_threshold_is_percent */
++ FALSE, /* quota_filecount_warn_threshold_is_percent */
+ TRUE, /* quota_is_inclusive */
+ FALSE, /* quota_no_check */
+ FALSE /* quota_filecount_no_check */
+@@ -311,10 +325,10 @@
+ ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file,
+ US"`maildir_use_size_file` in transport", tblock->name);
+
+-/* Loop for quota, quota_filecount, quota_warn_threshold, mailbox_size,
++/* Loop for quota, quota_filecount, quota_warn_threshold, quota_filecount_warn_threshold, mailbox_size,
+ mailbox_filecount */
+
+-for (i = 0; i < 5; i++)
++for (i = 0; i < 6; i++)
+ {
+ double d;
+ int no_check = 0;
+@@ -353,6 +367,18 @@
+ ob->quota_warn_threshold_is_percent = TRUE;
+ rest++;
+ }
++ else if (*rest == '%' && i == 3)
++ {
++ if (ob->quota_filecount_value <= 0 && !ob->maildir_use_size_file) d = 0;
++ else if ((int)d < 0 || (int)d > 100)
++ {
++ *errmsg = string_sprintf("Invalid quota_filecount_warn_threshold percentage (%d)"
++ " for %s transport", (int)d, tblock->name);
++ return FAIL;
++ }
++ ob->quota_filecount_warn_threshold_is_percent = TRUE;
++ rest++;
++ }
+
+
+ /* For quota and quota_filecount there may be options
+@@ -395,18 +421,26 @@
+ if (d >= 2.0*1024.0*1024.0*1024.0 && sizeof(off_t) <= 4)
+ which = US"quota_warn_threshold";
+ ob->quota_warn_threshold_value = (off_t)d;
++ q = ob->quota_filecount_warn_threshold;
++ default_value = -1.0;
++ break;
++
++ case 3:
++ if (d >= 2.0*1024.0*1024.0*1024.0 && sizeof(off_t) <= 4)
++ which = US"quota_filecount_warn_threshold";
++ ob->quota_filecount_warn_threshold_value = (off_t)d;
+ q = ob->mailbox_size_string;
+ default_value = -1.0;
+ break;
+
+- case 3:
++ case 4:
+ if (d >= 2.0*1024.0*1024.0*1024.0 && sizeof(off_t) <= 4)
+ which = US"mailbox_size";;
+ ob->mailbox_size_value = (off_t)d;
+ q = ob->mailbox_filecount_string;
+ break;
+
+- case 4:
++ case 5:
+ if (d >= 2.0*1024.0*1024.0*1024.0) which = US"mailbox_filecount";
+ ob->mailbox_filecount_value = (int)d;
+ break;
+@@ -557,13 +591,13 @@
+ not be used if the actual threshold for a given delivery ends up as zero,
+ of if it's given as a percentage and there's no quota setting. */
+
+-if (ob->quota_warn_threshold != NULL)
++if (ob->quota_warn_threshold != NULL || ob->quota_filecount_warn_threshold != NULL)
+ {
+ if (tblock->warn_message == NULL) tblock->warn_message = US
+ "To: $local_part@$domain\n"
+ "Subject: Your mailbox\n\n"
+ "This message is automatically created by mail delivery software (Exim).\n\n"
+- "The size of your mailbox has exceeded a warning threshold that is\n"
++ "The size or message count of your mailbox has exceeded a warning threshold that is\n"
+ "set by the system administrator.\n";
+ }
+
+@@ -1424,13 +1458,15 @@
+ {
+ debug_printf("appendfile: mode=%o notify_comsat=%d quota=" OFF_T_FMT
+ "%s"
+- " warning=" OFF_T_FMT "%s\n"
++ " warning=" OFF_T_FMT "%s / %d%s\n"
+ " %s=%s format=%s\n message_prefix=%s\n message_suffix=%s\n "
+ "maildir_use_size_file=%s\n",
+ mode, ob->notify_comsat, ob->quota_value,
+ ob->quota_no_check? " (no_check)" : "",
+ ob->quota_warn_threshold_value,
+ ob->quota_warn_threshold_is_percent? "%" : "",
++ ob->quota_filecount_warn_threshold_value,
++ ob->quota_filecount_warn_threshold_is_percent? "%" : "",
+ isdirectory? "directory" : "file",
+ path, mailbox_formats[mbformat],
+ (ob->message_prefix == NULL)? US"null" : string_printing(ob->message_prefix),
+@@ -3031,16 +3067,21 @@
+ if (!disable_quota && THRESHOLD_CHECK)
+ {
+ off_t threshold = ob->quota_warn_threshold_value;
++ int filecount_threshold = ob->quota_filecount_warn_threshold_value;
+ if (ob->quota_warn_threshold_is_percent)
+ threshold = (off_t)(((double)ob->quota_value * threshold) / 100);
++ if (ob->quota_filecount_warn_threshold_is_percent)
++ filecount_threshold = (int)(((double)ob->quota_filecount_value * filecount_threshold) / 100);
+ DEBUG(D_transport)
+ debug_printf("quota = " OFF_T_FMT
+- " threshold = " OFF_T_FMT
++ " threshold = " OFF_T_FMT "/%d"
+ " old size = " OFF_T_FMT
+- " message size = %d\n",
+- ob->quota_value, threshold, mailbox_size,
+- message_size);
+- if (mailbox_size <= threshold && mailbox_size + message_size > threshold)
++ " message size = %d"
++ " filecount = %d\n",
++ ob->quota_value, threshold, filecount_threshold, mailbox_size,
++ message_size, mailbox_filecount);
++ if ((mailbox_size <= threshold && mailbox_size + message_size > threshold)
++ ||(mailbox_filecount + 1 == filecount_threshold))
+ addr->special_action = SPECIAL_WARN;
+
+ /******* You might think that the test ought to be this:
+diff -r 8d6f7028bb88 src/transports/appendfile.h
+--- a/src/transports/appendfile.h Thu Jun 02 23:26:40 2011 +0200
++++ b/src/transports/appendfile.h Wed Jun 08 23:30:53 2011 +0200
+@@ -21,6 +21,7 @@
+ uschar *quota_filecount;
+ uschar *quota_size_regex;
+ uschar *quota_warn_threshold;
++ uschar *quota_filecount_warn_threshold;
+ uschar *mailbox_size_string;
+ uschar *mailbox_filecount_string;
+ uschar *expand_maildir_use_size_file;
+@@ -38,6 +39,7 @@
+ off_t mailbox_size_value;
+ int mailbox_filecount_value;
+ int quota_filecount_value;
++ int quota_filecount_warn_threshold_value;
+ int mode;
+ int dirmode;
+ int lockfile_mode;
+@@ -72,6 +74,7 @@
+ BOOL mailstore_format;
+ BOOL mbx_format;
+ BOOL quota_warn_threshold_is_percent;
++ BOOL quota_filecount_warn_threshold_is_percent;
+ BOOL quota_is_inclusive;
+ BOOL quota_no_check;
+ BOOL quota_filecount_no_check;