Check the length of off_t at build time and use %ld or %lld to print
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 16 Jun 2005 14:10:13 +0000 (14:10 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Thu, 16 Jun 2005 14:10:13 +0000 (14:10 +0000)
off_t values as appropriate. Assume that %lld is available if the size
of off_t is greater than 4. This involved some modifications to
string_vformat() in order to handle %lld.

doc/doc-txt/ChangeLog
src/src/buildconfig.c
src/src/deliver.c
src/src/expand.c
src/src/queue.c
src/src/rda.c
src/src/string.c
src/src/tls-gnu.c
src/src/transports/appendfile.c
src/src/transports/autoreply.c
src/src/transports/tf_maildir.c

index 5ff2e88..c377b93 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.156 2005/06/15 08:57:10 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.157 2005/06/16 14:10:13 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -120,6 +120,13 @@ PH/14 Imported PCRE 6.0; this was more than just a trivial operation because
       the sources for PCRE have been re-arranged and more files are now
       involved.
 
+PH/15 The code I had for printing potentially long long variables in PH/11
+      above was not the best (it lost precision). The length of off_t variables
+      is now inspected at build time, and an appropriate printing format (%ld
+      or %lld) is chosen and #defined by OFF_T_FMT. We also define ASSUME_
+      LONG_LONG_SUPPORT if the length is greater than 4. This is needed for the
+      internal formatting function string_vformat().
+
 
 Exim version 4.51
 -----------------
index 46bf473..ee5e431 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/buildconfig.c,v 1.7 2005/03/29 14:19:21 ph10 Exp $ */
+/* $Cambridge: exim/src/src/buildconfig.c,v 1.8 2005/06/16 14:10:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 /* This auxiliary program builds the file config.h by the following
 process:
 
-First it reads Makefile, looking for certain OS-specific definitions which it
-uses to define macros. Then it reads the defaults file config.h.defaults.
+First, it determines the size of off_t variables, and generates macro code to
+define OFF_T_FMT as a suitable format, if it is not already defined in the
+system-specific header file.
+
+Then it reads Makefile, looking for certain OS-specific definitions which it
+uses to define some specific macros. Finally, it reads the defaults file
+config.h.defaults.
 
 The defaults file contains normal C #define statements for various macros; if
 the name of a macro is found in the environment, the environment value replaces
@@ -96,6 +101,7 @@ if (!OK)
 int
 main(int argc, char **argv)
 {
+off_t test_off_t = 0;
 FILE *base;
 FILE *new;
 int last_initial = 'A';
@@ -132,7 +138,24 @@ fprintf(new, "using values specified in the configuration file Local/Makefile.\n
 fprintf(new, "Do not edit it. Instead, edit Local/Makefile and "
   "rerun make. */\n\n");
 
-/* First, search the makefile for certain settings */
+/* First, deal with the printing format for off_t variables. We assume that if
+the size of off_t is greater than 4, "%lld" will be available as a format for
+printing long long variables, and there will be support for the long long type.
+This assumption is known to be OK for the common operating systems. */
+
+fprintf(new, "#ifndef OFF_T_FMT\n");
+if (sizeof(test_off_t) > 4)
+  {
+  fprintf(new, "#define OFF_T_FMT  \"%%lld\"\n");
+  fprintf(new, "#define ASSUME_LONG_LONG_SUPPORT\n");
+  }
+else
+  {
+  fprintf(new, "#define OFF_T_FMT  \"%%ld\"\n");
+  }
+fprintf(new, "#endif\n\n");
+
+/* Now search the makefile for certain settings */
 
 base = fopen("Makefile", "rb");
 if (base == NULL)
index c183c86..2568c97 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/deliver.c,v 1.17 2005/06/14 13:48:40 ph10 Exp $ */
+/* $Cambridge: exim/src/src/deliver.c,v 1.18 2005/06/16 14:10:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -4482,8 +4482,8 @@ if ((rc = spool_read_header(spoolname, TRUE, TRUE)) != spool_read_OK)
     sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir,
       spoolname);
     if (Ustat(big_buffer, &statbuf) == 0)
-      log_write(0, LOG_MAIN, "Format error in spool file %s: size=%.30g",
-        spoolname, (double)statbuf.st_size);
+      log_write(0, LOG_MAIN, "Format error in spool file %s: "
+        "size=" OFF_T_FMT, spoolname, statbuf.st_size);
     else log_write(0, LOG_MAIN, "Format error in spool file %s", spoolname);
     }
   else
@@ -6345,8 +6345,8 @@ wording. */
             if (emf_text != NULL) fprintf(f, "%s", CS emf_text); else
               {
               fprintf(f,
-"------ The body of the message is %.30g characters long; only the first\n"
-"------ %d or so are included here.\n", (double)statbuf.st_size, max);
+"------ The body of the message is " OFF_T_FMT " characters long; only the first\n"
+"------ %d or so are included here.\n", statbuf.st_size, max);
               }
             }
           }
index 0ae3259..7ecfc09 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.25 2005/06/13 13:37:39 fanf2 Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.26 2005/06/16 14:10:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -4540,10 +4540,10 @@ while (*s != 0)
 
         smode[10] = 0;
         s = string_sprintf("mode=%04lo smode=%s inode=%ld device=%ld links=%ld "
-          "uid=%ld gid=%ld size=%.30g atime=%ld mtime=%ld ctime=%ld",
+          "uid=%ld gid=%ld size=" OFF_T_FMT " atime=%ld mtime=%ld ctime=%ld",
           (long)(st.st_mode & 077777), smode, (long)st.st_ino,
           (long)st.st_dev, (long)st.st_nlink, (long)st.st_uid,
-          (long)st.st_gid, (double)st.st_size, (long)st.st_atime,
+          (long)st.st_gid, st.st_size, (long)st.st_atime,
           (long)st.st_mtime, (long)st.st_ctime);
         yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
         continue;
index a443fdf..f411f36 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/queue.c,v 1.6 2005/06/07 15:20:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/queue.c,v 1.7 2005/06/16 14:10:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -895,8 +895,8 @@ for (; f != NULL; f = f->next)
       sprintf(CS big_buffer, "%s/input/%s/%s", spool_directory, message_subdir,
         f->text);
       if (Ustat(big_buffer, &statbuf) == 0)
-        printf("*** spool format error: size=%.30g ***",
-          (double)statbuf.st_size);
+        printf("*** spool format error: size=" OFF_T_FMT " ***",
+          statbuf.st_size);
       else printf("*** spool format error ***");
       }
     else printf("*** spool read error: %s ***", strerror(save_errno));
index 8f972ca..1be7b1c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/rda.c,v 1.6 2005/06/07 15:20:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/rda.c,v 1.7 2005/06/16 14:10:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -300,7 +300,7 @@ if (fread(filebuf, 1, statbuf.st_size, fwd) != statbuf.st_size)
 filebuf[statbuf.st_size] = 0;
 
 DEBUG(D_route)
-  debug_printf("%.30g bytes read from %s\n", (double)statbuf.st_size, filename);
+  debug_printf(OFF_T_FMT " bytes read from %s\n", statbuf.st_size, filename);
 
 fclose(fwd);
 return filebuf;
index ba04aa4..aa4f933 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/string.c,v 1.4 2005/06/07 15:20:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/string.c,v 1.5 2005/06/16 14:10:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -973,6 +973,8 @@ return yield;
 BOOL
 string_vformat(uschar *buffer, int buflen, char *format, va_list ap)
 {
+enum { L_NORMAL, L_SHORT, L_LONG, L_LONGLONG, L_LONGDOUBLE };
+
 BOOL yield = TRUE;
 int width, precision;
 char *fp = format;             /* Deliberately not unsigned */
@@ -985,6 +987,7 @@ string_datestamp_offset = -1;  /* Datestamp not inserted */
 
 while (*fp != 0)
   {
+  int length = L_NORMAL;
   int *nptr;
   int slen;
   char *null = "NULL";         /* ) These variables */
@@ -1038,7 +1041,25 @@ while (*fp != 0)
       }
     }
 
-  if (strchr("hlL", *fp) != NULL) fp++;
+  /* Skip over 'h', 'L', 'l', and 'll', remembering the item length */
+
+  if (*fp == 'h')
+    { fp++; length = L_SHORT; }
+  else if (*fp == 'L')
+    { fp++; length = L_LONGDOUBLE; }
+  else if (*fp == 'l')
+    {
+    if (fp[1] == 'l')
+      {
+      fp += 2;
+      length = L_LONGLONG;
+      }
+    else
+      {
+      fp++;
+      length = L_LONG;
+      }
+    }
 
   /* Handle each specific format type. */
 
@@ -1054,10 +1075,24 @@ while (*fp != 0)
     case 'u':
     case 'x':
     case 'X':
-    if (p >= last - 12) { yield = FALSE; goto END_FORMAT; }
+    if (p >= last - 24) { yield = FALSE; goto END_FORMAT; }
     strncpy(newformat, item_start, fp - item_start);
     newformat[fp - item_start] = 0;
-    sprintf(CS p, newformat, va_arg(ap, int));
+
+    /* Short int is promoted to int when passing through ..., so we must use
+    int for va_arg(). */
+
+    switch(length)
+      {
+      case L_SHORT:
+      case L_NORMAL:   sprintf(CS p, newformat, va_arg(ap, int)); break;
+      case L_LONG:     sprintf(CS p, newformat, va_arg(ap, long int)); break;
+      #ifdef ASSUME_LONG_LONG_SUPPORT
+      case L_LONGLONG: sprintf(CS p, newformat, va_arg(ap, long long int)); break;
+      #else
+      case L_LONGLONG: sprintf(CS p, newformat, va_arg(ap, long long int)); break;
+      #endif
+      }
     while (*p) p++;
     break;
 
@@ -1085,7 +1120,10 @@ while (*fp != 0)
     if (p >= last - precision - 8) { yield = FALSE; goto END_FORMAT; }
     strncpy(newformat, item_start, fp - item_start);
     newformat[fp-item_start] = 0;
-    sprintf(CS p, newformat, va_arg(ap, double));
+    if (length == L_LONGDOUBLE)
+      sprintf(CS p, newformat, va_arg(ap, long double));
+    else
+      sprintf(CS p, newformat, va_arg(ap, double));
     while (*p) p++;
     break;
 
index 723d97b..aedf09b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/tls-gnu.c,v 1.7 2005/06/07 15:20:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/tls-gnu.c,v 1.8 2005/06/16 14:10:13 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -499,8 +499,8 @@ if (cas != NULL)
     return DEFER;
     }
 
-  DEBUG(D_tls) debug_printf("verify certificates = %s size=%.30g\n",
-    cas_expanded, (double)statbuf.st_size);
+  DEBUG(D_tls) debug_printf("verify certificates = %s size=" OFF_T_FMT "\n",
+    cas_expanded, statbuf.st_size);
 
   /* If the cert file is empty, there's no point in loading the CRL file. */
 
index 6874fa7..b17eb3b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.7 2005/06/07 15:20:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.8 2005/06/16 14:10:14 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -559,7 +559,7 @@ uschar buffer[256];
 
 DEBUG(D_transport) debug_printf("notify_comsat called\n");
 
-sprintf(CS buffer, "%.200s@%.30g\n", user, (double)offset);
+sprintf(CS buffer, "%.200s@" OFF_T_FMT "\n", user, offset);
 
 if ((sp = getservbyname("biff", "udp")) == NULL)
   {
@@ -741,8 +741,8 @@ while ((ent = readdir(dir)) != NULL)
         {
         sum += size;
         DEBUG(D_transport)
-          debug_printf("check_dir_size: size from %s is %.30g\n", name,
-            (double)size);
+          debug_printf("check_dir_size: size from %s is " OFF_T_FMT "\n", name,
+            size);
         continue;
         }
       }
@@ -776,8 +776,8 @@ while ((ent = readdir(dir)) != NULL)
 
 closedir(dir);
 DEBUG(D_transport)
-  debug_printf("check_dir_size: dir=%s sum=%.30g count=%d\n", dirname,
-    (double)sum, count);
+  debug_printf("check_dir_size: dir=%s sum=" OFF_T_FMT " count=%d\n", dirname,
+    sum, count);
 
 *countptr = count;
 return sum;
@@ -909,8 +909,8 @@ size, including CRLFs, which is the size of the input (temporary) file. */
 if (fstat(from_fd, &statbuf) < 0) return DEFER;
 size = statbuf.st_size;
 
-sprintf (CS deliver_out_buffer, "%s,%.30g;%08lx%04x-%08x\015\012",
-  tod_stamp(tod_mbx), (double)size, 0L, 0, 0);
+sprintf (CS deliver_out_buffer, "%s," OFF_T_FMT ";%08lx%04x-%08x\015\012",
+  tod_stamp(tod_mbx), size, 0L, 0, 0);
 used = Ustrlen(deliver_out_buffer);
 
 /* Rewind the temporary file, and copy it over in chunks. */
@@ -1342,12 +1342,12 @@ else
 
 DEBUG(D_transport)
   {
-  debug_printf("appendfile: mode=%o notify_comsat=%d quota=%.30g "
-    "warning=%.30g%s\n"
+  debug_printf("appendfile: mode=%o notify_comsat=%d quota=" OFF_T_FMT
+    " warning=" OFF_T_FMT "%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, (double)ob->quota_value,
-    (double)ob->quota_warn_threshold_value,
+    mode, ob->notify_comsat, ob->quota_value,
+    ob->quota_warn_threshold_value,
     ob->quota_warn_threshold_is_percent? "%" : "",
     isdirectory? "directory" : "file",
     path, mailbox_formats[mbformat],
@@ -2582,9 +2582,10 @@ if (ob->quota_value > 0)
   {
   DEBUG(D_transport)
     {
-    debug_printf("Exim quota = %.30g old size = %.30g this message = %d "
-      "(%sincluded)\n", (double)ob->quota_value, (double)mailbox_size,
-      message_size, ob->quota_is_inclusive? "" : "not ");
+    debug_printf("Exim quota = " OFF_T_FMT " old size = " OFF_T_FMT
+      " this message = %d (%sincluded)\n",
+      ob->quota_value, mailbox_size, message_size,
+      ob->quota_is_inclusive? "" : "not ");
     debug_printf("  file count quota = %d count = %d\n",
       ob->quota_filecount_value, mailbox_filecount);
     }
@@ -2768,9 +2769,11 @@ if (THRESHOLD_CHECK)
   if (ob->quota_warn_threshold_is_percent)
     threshold = (off_t)(((double)ob->quota_value * threshold) / 100);
   DEBUG(D_transport)
-    debug_printf("quota = %.30g threshold = %.30g old size = %.30g "
-      "message size = %d\n",
-      (double)ob->quota_value, (double)threshold, (double)mailbox_size,
+    debug_printf("quota = " OFF_T_FMT
+      " threshold = " OFF_T_FMT
+      " 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)
     addr->special_action = SPECIAL_WARN;
index 7c1af15..e6a2931 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/autoreply.c,v 1.3 2005/06/07 15:20:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/autoreply.c,v 1.4 2005/06/16 14:10:14 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -643,8 +643,8 @@ if (return_message)
       {
       fprintf(f, "\n"
 "------ This is a copy of the message, including all the headers.\n"
-"------ The body of the message is %.30g characters long; only the first\n"
-"------ %d or so are included here.\n\n", (double)statbuf.st_size,
+"------ The body of the message is " OFF_T_FMT " characters long; only the first\n"
+"------ %d or so are included here.\n\n", statbuf.st_size,
         (max/1000)*1000);
       }
     else fprintf(f, "\n"
index 17f24d7..5277ef0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/tf_maildir.c,v 1.5 2005/06/07 15:20:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/tf_maildir.c,v 1.6 2005/06/16 14:10:14 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -282,8 +282,9 @@ DEBUG(D_transport)
     debug_printf("maildir_compute_size (timestamp_only): %ld\n",
     (long int) *latest);
   else
-    debug_printf("maildir_compute_size: path=%s\n  sum=%.30g filecount=%d "
-      "timestamp=%ld\n", path, (double)sum, *filecount, (long int) *latest);
+    debug_printf("maildir_compute_size: path=%s\n  sum=" OFF_T_FMT
+      " filecount=%d timestamp=%ld\n",
+      path, sum, *filecount, (long int) *latest);
   }
 return sum;
 }
@@ -404,9 +405,9 @@ if (cached_quota != ob->quota_value ||
   {
   DEBUG(D_transport)
     debug_printf("cached quota is out of date: recalculating\n"
-      "  quota=%.30g cached_quota=%.30g filecount_quota=%d "
-      "cached_quota_filecount=%d\n", (double)ob->quota_value,
-      (double)cached_quota, ob->quota_filecount_value, cached_quota_filecount);
+      "  quota=" OFF_T_FMT " cached_quota=" OFF_T_FMT " filecount_quota=%d "
+      "cached_quota_filecount=%d\n", ob->quota_value,
+      cached_quota, ob->quota_filecount_value, cached_quota_filecount);
   goto RECALCULATE;
   }
 
@@ -439,7 +440,7 @@ if (*endptr == 0)
   if (size < 0 || filecount < 0)
     {
     DEBUG(D_transport) debug_printf("negative value in maildirsize "
-      "(size=%.30g count=%d): recalculating\n", (double)size, filecount);
+      "(size=" OFF_T_FMT " count=%d): recalculating\n", size, filecount);
     goto RECALCULATE;
     }
 
@@ -510,8 +511,8 @@ else
   fd = Uopen(tempname, O_RDWR|O_CREAT|O_EXCL, 0600);
   if (fd >= 0)
     {
-    (void)sprintf(CS buffer, "%.30gS,%dC\n%.30g %d\n", (double)ob->quota_value,
-      ob->quota_filecount_value, (double)size, filecount);
+    (void)sprintf(CS buffer, OFF_T_FMT "S,%dC\n" OFF_T_FMT " %d\n",
+      ob->quota_value, ob->quota_filecount_value, size, filecount);
     len = Ustrlen(buffer);
     if (write(fd, buffer, len) != len || Urename(tempname, filename) < 0)
       {
@@ -538,8 +539,8 @@ else
 
 /* Return the sizes and the file descriptor, if any */
 
-DEBUG(D_transport) debug_printf("returning maildir size=%.30g filecount=%d\n",
-  (double)size, filecount);
+DEBUG(D_transport) debug_printf("returning maildir size=" OFF_T_FMT
+  " filecount=%d\n", size, filecount);
 *returned_size = size;
 *returned_filecount = filecount;
 return fd;