Re: [exim] Quota over 2GB supported?

Top Page
Delete this message
Reply to this message
Author: Christian Kuehn
Date:  
To: exim-users
Subject: Re: [exim] Quota over 2GB supported?
Is this problem fixed in 4.51 (rc released today by Philip) ??

Best Regards
Christian

Michael Haardt wrote:
> 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 */
>