Increase size of variables for check_spool_space and check_log_space
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 21 May 2017 13:09:43 +0000 (14:09 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 30 Oct 2018 01:00:51 +0000 (01:00 +0000)
doc/doc-txt/ChangeLog
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/readconf.c
src/src/receive.c
test/confs/0180
test/paniclog/0415
test/scripts/0000-Basic/0415
test/stderr/0415
test/stdout/0415

index 70a496259c37349d147ea8368628660f617fb79c..2407812238c507ad5e72edac606b38a079b802f5 100644 (file)
@@ -146,6 +146,11 @@ JH/31 Fix a bad use of a copy function, which could be used to pointlessly
       copy a string over itself.  The library routine is documented as not
       supporting overlapping copies, and on MacOS it actually raised a SIGABRT.
 
+JH/32 For main options check_spool_space and check_inode_space, where the
+      platform supports 64b integers, support more than the previous 2^31 kB
+      (i.e. more than 2 TB).  Accept E, P and T multipliers in addition to
+      the previous G, M, k.
+
 
 Exim version 4.91
 -----------------
index f37c10733445c7d26de9599f237438d4de8e737a..38df27aea21dfaed4b6b222caf6bf6fa1d5bf6f9 100644 (file)
@@ -376,7 +376,7 @@ extern void    receive_bomb_out(uschar *, uschar *);
 extern BOOL    receive_check_fs(int);
 extern BOOL    receive_check_set_sender(uschar *);
 extern BOOL    receive_msg(BOOL);
-extern int     receive_statvfs(BOOL, int *);
+extern int_eximarith_t receive_statvfs(BOOL, int *);
 extern void    receive_swallow_smtp(void);
 #ifdef WITH_CONTENT_SCAN
 extern int     regex(const uschar **);
index f8a4c3c0d78602f4b2f7d59c6a5194ea2eb6ae2f..8dd8191efe7c308b78311621c8c9d5690da17711 100644 (file)
@@ -704,9 +704,9 @@ int     callout_cache_negative_expire = 2*60*60;
 uschar *callout_random_local_part = US"$primary_hostname-$tod_epoch-testing";
 uschar *check_dns_names_pattern= US"(?i)^(?>(?(1)\\.|())[^\\W](?>[a-z0-9/_-]*[^\\W])?)+(\\.?)$";
 int     check_log_inodes       = 100;
-int     check_log_space        = 10*1024;      /* 10K Kbyte == 10MB */
+int_eximarith_t check_log_space = 10*1024;     /* 10K Kbyte == 10MB */
 int     check_spool_inodes     = 100;
-int     check_spool_space      = 10*1024;      /* 10K Kbyte == 10MB */
+int_eximarith_t check_spool_space = 10*1024;   /* 10K Kbyte == 10MB */
 
 uschar *chunking_advertise_hosts = US"*";
 unsigned chunking_datasize     = 0;
index d337d3b75d422f71bb3d49d86f4b4ad29067d4f0..465266e1a5f3396667d5bc6652c9d6e69c5dda49 100644 (file)
@@ -382,10 +382,10 @@ extern int     callout_cache_negative_expire; /* Time for negative callout cache
 extern uschar *callout_random_local_part; /* Local part to be used to check if server called will accept any local part */
 extern uschar *check_dns_names_pattern;/* Regex for syntax check */
 extern int     check_log_inodes;       /* Minimum for message acceptance */
-extern int     check_log_space;        /* Minimum for message acceptance */
+extern int_eximarith_t check_log_space; /* Minimum for message acceptance */
 extern BOOL    check_rfc2047_length;   /* Check RFC 2047 encoded string length */
 extern int     check_spool_inodes;     /* Minimum for message acceptance */
-extern int     check_spool_space;      /* Minimum for message acceptance */
+extern int_eximarith_t check_spool_space; /* Minimum for message acceptance */
 extern uschar *chunking_advertise_hosts;    /* RFC 3030 CHUNKING */
 extern unsigned chunking_datasize;
 extern unsigned chunking_data_left;
index a49d6c285ba456c530d143ecc9dcd6f26d3d9501..9b3eef3673f1d798438f21c7597d7f05883a5824 100644 (file)
@@ -2141,80 +2141,77 @@ switch (type)
       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
         inttype, name);
 
-    if (errno != ERANGE)
-      if (tolower(*endptr) == 'k')
-        {
-        if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE;
-          else lvalue *= 1024;
-        endptr++;
-        }
-      else if (tolower(*endptr) == 'm')
-        {
-        if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024))
-          errno = ERANGE;
-        else lvalue *= 1024*1024;
-        endptr++;
-        }
-      else if (tolower(*endptr) == 'g')
-        {
-        if (lvalue > INT_MAX/(1024*1024*1024) || lvalue < INT_MIN/(1024*1024*1024))
-          errno = ERANGE;
-        else lvalue *= 1024*1024*1024;
-        endptr++;
-        }
+    if (errno != ERANGE && *endptr)
+      {
+      uschar * mp = US"GgMmKk\0";      /* YyZzEePpTtGgMmKk */
+
+      if ((mp = Ustrchr(mp, *endptr)))
+       {
+       endptr++;
+       do
+         {
+         if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024)
+           {
+           errno = ERANGE;
+           break;
+           }
+         lvalue *= 1024;
+         }
+       while (*(mp += 2));
+       }
+      }
 
     if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN)
       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
         "absolute value of integer \"%s\" is too large (overflow)", s);
 
     while (isspace(*endptr)) endptr++;
-    if (*endptr != 0)
+    if (*endptr)
       extra_chars_error(endptr, inttype, US"integer value for ", name);
 
     value = (int)lvalue;
     }
 
-  if (data_block == NULL)
-    *((int *)(ol->value)) = value;
+  if (data_block)
+    *(int *)(US data_block + (long int)ol->value) = value;
   else
-    *((int *)(US data_block + (long int)(ol->value))) = value;
+    *(int *)ol->value = value;
   break;
 
-  /*  Integer held in K: again, allow octal and hex formats, and suffixes K, M
-  and G. */
-  /*XXX consider moving to int_eximarith_t (but mind the overflow test 0415) */
+  /*  Integer held in K: again, allow octal and hex formats, and suffixes K, M,
+  G and T. */
 
   case opt_Kint:
     {
     uschar *endptr;
     errno = 0;
-    value = strtol(CS s, CSS &endptr, intbase);
+    int_eximarith_t lvalue = strtol(CS s, CSS &endptr, intbase);
 
     if (endptr == s)
       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
         inttype, name);
 
-    if (errno != ERANGE)
-      if (tolower(*endptr) == 'g')
-        {
-        if (value > INT_MAX/(1024*1024) || value < INT_MIN/(1024*1024))
-         errno = ERANGE;
-       else
-         value *= 1024*1024;
-        endptr++;
-        }
-      else if (tolower(*endptr) == 'm')
-        {
-        if (value > INT_MAX/1024 || value < INT_MIN/1024)
-         errno = ERANGE;
-       else
-         value *= 1024;
-        endptr++;
-        }
-      else if (tolower(*endptr) == 'k')
-        endptr++;
+    if (errno != ERANGE && *endptr)
+      {
+      uschar * mp = US"EePpTtGgMmKk\0";        /* YyZzEePpTtGgMmKk */
+
+      if ((mp = Ustrchr(mp, *endptr)))
+       {
+       endptr++;
+       do
+         {
+         if (lvalue > EXIM_ARITH_MAX/1024 || lvalue < EXIM_ARITH_MIN/1024)
+           {
+           errno = ERANGE;
+           break;
+           }
+         lvalue *= 1024;
+         }
+       while (*(mp += 2));
+       }
       else
-        value = (value + 512)/1024;
+       lvalue = (lvalue + 512)/1024;
+      }
 
     if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
       "absolute value of integer \"%s\" is too large (overflow)", s);
@@ -2222,13 +2219,13 @@ switch (type)
     while (isspace(*endptr)) endptr++;
     if (*endptr != 0)
       extra_chars_error(endptr, inttype, US"integer value for ", name);
-    }
 
-  if (data_block == NULL)
-    *((int *)(ol->value)) = value;
-  else
-    *((int *)(US data_block + (long int)(ol->value))) = value;
-  break;
+    if (data_block)
+      *(int_eximarith_t *)(US data_block + (long int)ol->value) = lvalue;
+    else
+      *(int_eximarith_t *)ol->value = lvalue;
+    break;
+    }
 
   /*  Fixed-point number: held to 3 decimal places. */
 
@@ -2485,11 +2482,12 @@ switch(ol->type & opt_mask)
 
   case opt_Kint:
     {
-    int x = *((int *)value);
+    int_eximarith_t x = *((int_eximarith_t *)value);
     if (!no_labels) printf("%s = ", name);
     if (x == 0) printf("0\n");
-    else if ((x & 1023) == 0) printf("%dM\n", x >> 10);
-    else printf("%dK\n", x);
+    else if ((x & ((1<<20)-1)) == 0) printf(PR_EXIM_ARITH "G\n", x >> 20);
+    else if ((x & ((1<<10)-1)) == 0) printf(PR_EXIM_ARITH "M\n", x >> 10);
+    else printf(PR_EXIM_ARITH "K\n", x);
     }
     break;
 
index cd7867d049bc1be423f18e6e081b0b5d29d9ebfe..ab27cc3738bad3f8cd930b527ec5711d327a0e89 100644 (file)
@@ -144,7 +144,7 @@ Returns:        available on-root space, in kilobytes
 All values are -1 if the STATFS functions are not available.
 */
 
-int
+int_eximarith_t
 receive_statvfs(BOOL isspool, int *inodeptr)
 {
 #ifdef HAVE_STATFS
@@ -223,7 +223,7 @@ if (STATVFS(CS path, &statbuf) != 0)
 
 /* Disks are getting huge. Take care with computing the size in kilobytes. */
 
-return (int)(((double)statbuf.F_BAVAIL * (double)statbuf.F_FRSIZE)/1024.0);
+return (int_eximarith_t)(((double)statbuf.F_BAVAIL * (double)statbuf.F_FRSIZE)/1024.0);
 
 #else
 /* Unable to find partition sizes in this environment. */
@@ -258,7 +258,8 @@ Returns:       FALSE if there isn't enough space, or if the information cannot
 BOOL
 receive_check_fs(int msg_size)
 {
-int space, inodes;
+int_eximarith_t space;
+int inodes;
 
 if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0)
   {
@@ -266,7 +267,7 @@ if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0)
 
   DEBUG(D_receive)
     debug_printf("spool directory space = %dK inodes = %d "
-      "check_space = %dK inodes = %d msg_size = %d\n",
+      "check_space = " PR_EXIM_ARITH "K inodes = %d msg_size = %d\n",
       space, inodes, check_spool_space, check_spool_inodes, msg_size);
 
   if ((space >= 0 && space < check_spool_space) ||
@@ -284,7 +285,7 @@ if (check_log_space > 0 || check_log_inodes > 0)
 
   DEBUG(D_receive)
     debug_printf("log directory space = %dK inodes = %d "
-      "check_space = %dK inodes = %d\n",
+      "check_space = " PR_EXIM_ARITH "K inodes = %d\n",
       space, inodes, check_log_space, check_log_inodes);
 
   if ((space >= 0 && space < check_log_space) ||
index c4a0bd5af631e7ae871291544ac686e0c9e63a01..e90d54517b2c84c8e70cfd3a2090c92341dfd997 100644 (file)
@@ -1,7 +1,7 @@
 # Exim test configuration 0180
 
 # Require immense amount of disk space, expecting to fail.  Can unfortunately work on big filesystems.
-CSS=check_spool_space=400G
+CSS=check_spool_space=1024T
 
 .include DIR/aux-var/std_conf_prefix
 
index 2ed26d3f303b7e8be6b7aaf9023e242e9fc7cbd0..e0fbdedf309e235301bc0da2999f197147c33bb2 100644 (file)
@@ -1,5 +1,5 @@
 1999-03-02 09:44:33 Exim configuration error in line 15 of TESTSUITE/test-config:
-  absolute value of integer "4000000M" is too large (overflow)
+  absolute value of integer "4000E" is too large (overflow)
 1999-03-02 09:44:33 Exim configuration error in line 15 of TESTSUITE/test-config:
   extra characters follow integer value for check_spool_space
 1999-03-02 09:44:33 Exim configuration error in line 16 of TESTSUITE/test-config:
index 29628b87ab8f0aa3ee53e3abb6846974bad4af09..043258fc053c6dbff5071f4b045fed8029575432 100644 (file)
@@ -1,6 +1,8 @@
 # overflow in integer options
 1
-exim -DARG1=4000000M -bP check_spool_space
+exim -DARG1=4000E -bP check_spool_space
+****
+exim -DARG1=4000G -bP check_spool_space
 ****
 1
 exim -DARG1=40MK -bP check_spool_space
index f2c8612e86cbdf2f52bb19941047b3f558e31d39..55cc46fd13aa982929e7eda0b62b7f0a1303e9e9 100644 (file)
@@ -1,6 +1,6 @@
 LOG: PANIC DIE
   Exim configuration error in line 15 of TESTSUITE/test-config:
-  absolute value of integer "4000000M" is too large (overflow)
+  absolute value of integer "4000E" is too large (overflow)
 LOG: PANIC DIE
   Exim configuration error in line 15 of TESTSUITE/test-config:
   extra characters follow integer value for check_spool_space
index f1183c8385d2812fa98e925e8198ed0a71bbab01..0dfbae86525c9a7bce6364e974d9f49519f38202 100644 (file)
@@ -1,3 +1,4 @@
+check_spool_space = 4096000G
 finduser_retries = 0
 finduser_retries = 999999999
 finduser_retries = 1023998976