Here is a patch that works for me [tm]. It allows quota of 2 GB and more
on machines with large file support, but does not support maildirsize
and large messages. It is probably not complete in other ways, too.
I don't particularly like the loop to convert values, but Philip will
probably make his own patch anyway. This patch may suffice until then.
Michael
----------------------------------------------------------------------
--- src/transports/appendfile.c.ph 2005-04-08 16:24:40.000000000 +0200
+++ src/transports/appendfile.c 2005-04-12 23:39:57.000000000 +0200
@@ -232,6 +232,21 @@
};
+const unsigned char *offtostr(off_t n)
+ {
+ static unsigned char buf[128];
+ unsigned char *t;
+ size_t size,capacity;
+
+ size=capacity=0;
+ t=buf+sizeof(buf)-1;
+ *t='\0';
+ if (n==0) *--t='0';
+ else while (n) { *--t=n%10+'0'; n/=10; }
+ return string_cat(NULL,&size,&capacity,t,buf-t+1);
+ }
+
+
/*************************************************
* Setup entry point *
@@ -259,8 +274,7 @@
appendfile_transport_options_block *ob =
(appendfile_transport_options_block *)(tblock->options_block);
uschar *q = ob->quota;
-int *v = &(ob->quota_value);
-int default_value = 0;
+double default_value = 0.0;
int i;
addrlist = addrlist; /* Keep picky compilers happy */
@@ -271,9 +285,10 @@
for (i = 0; i < 5; i++)
{
- if (q == NULL) *v = default_value; else
+ double d;
+
+ if (q == NULL) d = default_value; else
{
- double d;
uschar *rest;
uschar *s = expand_string(q);
@@ -292,6 +307,7 @@
if (tolower(*rest) == 'k') { d *= 1024.0; rest++; }
else if (tolower(*rest) == 'm') { d *= 1024.0*1024.0; rest++; }
+ else if (tolower(*rest) == 'g') { d *= 1024.0*1024.0*1024.0; rest++; }
else if (*rest == '%' && i == 2)
{
if (ob->quota_value <= 0 && !ob->maildir_use_size_file) d = 0;
@@ -314,30 +330,33 @@
return FAIL;
}
- *v = (int)d;
}
switch (i)
{
case 0:
+ ob->quota_value = (off_t)d;
q = ob->quota_filecount;
- v = &(ob->quota_filecount_value);
break;
case 1:
+ ob->quota_filecount_value = (int)d;
q = ob->quota_warn_threshold;
- v = &(ob->quota_warn_threshold_value);
break;
case 2:
+ ob->quota_warn_threshold_value = (off_t)d;
q = ob->mailbox_size_string;
- v = &(ob->mailbox_size_value);
- default_value = -1;
+ default_value = -1.0;
break;
case 3:
+ ob->mailbox_size_value = (off_t)d;
q = ob->mailbox_filecount_string;
- v = &(ob->mailbox_filecount_value);
+ break;
+
+ case 4:
+ ob->mailbox_filecount_value = (int)d;
break;
}
}
@@ -704,11 +723,11 @@
zero if the directory cannot be opened
*/
-int
+off_t
check_dir_size(uschar *dirname, int *countptr, const pcre *regex)
{
DIR *dir;
-int sum = 0;
+off_t sum = 0;
int count = *countptr;
struct dirent *ent;
struct stat statbuf;
@@ -738,7 +757,7 @@
{
sum += size;
DEBUG(D_transport)
- debug_printf("check_dir_size: size from %s is %d\n", name, size);
+ debug_printf("check_dir_size: size from %s is %s\n", name, offtostr(size));
continue;
}
}
@@ -772,7 +791,7 @@
closedir(dir);
DEBUG(D_transport)
- debug_printf("check_dir_size: dir=%s sum=%d count=%d\n", dirname, sum, count);
+ debug_printf("check_dir_size: dir=%s sum=%s count=%d\n", dirname, offtostr(sum), count);
*countptr = count;
return sum;
}
@@ -890,11 +909,11 @@
int ovector[6];
if (pcre_exec(regex, NULL, CS name, Ustrlen(name), 0, 0, ovector,6) >= 2)
{
- size = Ustrtol(name + ovector[2], &endptr, 10);
+ size = (off_t)Ustrtod(name + ovector[2], &endptr);
if (endptr == name + ovector[3])
{
DEBUG(D_transport)
- debug_printf("scan_mails: matched size from %s is %d\n", name, size);
+ debug_printf("scan_mails: matched size from %s is %s\n", name, offtostr(size));
goto skip_stat;
}
}
@@ -1098,7 +1117,7 @@
static int
copy_mbx_message(int to_fd, int from_fd, int saved_size)
{
-int used, size;
+off_t used, size;
struct stat statbuf;
/* If the current mailbox size is zero, write a header block */
@@ -1427,8 +1446,8 @@
gid_t gid = getegid();
int mbformat;
int mode = (addr->mode > 0)? addr->mode : ob->mode;
-int saved_size = -1;
-int mailbox_size = ob->mailbox_size_value;
+off_t saved_size = -1;
+off_t mailbox_size = ob->mailbox_size_value;
int mailbox_filecount = ob->mailbox_filecount_value;
int hd = -1;
int fd = -1;
@@ -1557,10 +1576,10 @@
DEBUG(D_transport)
{
- debug_printf("appendfile: mode=%o notify_comsat=%d quota=%d warning=%d%s\n"
+ debug_printf("appendfile: mode=%o notify_comsat=%d quota=%s warning=%s%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_warn_threshold_value,
+ mode, ob->notify_comsat, offtostr(ob->quota_value), offtostr(ob->quota_warn_threshold_value),
ob->quota_warn_threshold_is_percent? "%" : "",
isdirectory? "directory" : "file",
path, mailbox_formats[mbformat],
@@ -2523,7 +2542,7 @@
if ((mailbox_size < 0 || mailbox_filecount < 0) &&
(ob->quota_value > 0 || THRESHOLD_CHECK))
{
- int size;
+ off_t size;
int filecount = 0;
DEBUG(D_transport)
debug_printf("quota checks on directory %s\n", check_path);
@@ -2801,8 +2820,8 @@
{
DEBUG(D_transport)
{
- debug_printf("Exim quota = %d old size = %d this message = %d "
- "(%sincluded)\n", ob->quota_value, mailbox_size, message_size,
+ debug_printf("Exim quota = %s old size = %s this message = %d "
+ "(%sincluded)\n", offtostr(ob->quota_value), offtostr(mailbox_size), message_size,
ob->quota_is_inclusive? "" : "not ");
debug_printf(" file count quota = %d count = %d\n",
ob->quota_filecount_value, mailbox_filecount);
@@ -2987,8 +3006,8 @@
if (ob->quota_warn_threshold_is_percent)
threshold = (int)(((double)ob->quota_value * threshold) / 100);
DEBUG(D_transport)
- debug_printf("quota = %d threshold = %d old size = %d message size = %d\n",
- ob->quota_value, threshold, mailbox_size, message_size);
+ debug_printf("quota = %s threshold = %s old size = %s message size = %d\n",
+ offtostr(ob->quota_value), offtostr(threshold), offtostr(mailbox_size), message_size);
if (mailbox_size <= threshold && mailbox_size + message_size > threshold)
addr->special_action = SPECIAL_WARN;
--- src/transports/appendfile.h.orig 2005-04-12 23:02:24.000000000 +0200
+++ src/transports/appendfile.h 2005-04-12 23:03:34.000000000 +0200
@@ -32,7 +32,7 @@
uschar *file_format;
int mailbox_size_value;
int mailbox_filecount_value;
- int quota_value;
+ off_t quota_value;
int quota_filecount_value;
int quota_warn_threshold_value;
int mode;
@@ -92,6 +92,6 @@
/* Function that is shared with tf_maildir.c */
-extern int check_dir_size(uschar *, int *, const pcre *);
+extern off_t check_dir_size(uschar *, int *, const pcre *);
/* End of transports/appendfile.h */