From b1c749bb7f147e7f9215fe6067c848cf02938b92 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Thu, 16 Jun 2005 14:10:13 +0000 Subject: [PATCH] Check the length of off_t at build time and use %ld or %lld to print 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 | 9 ++++++- src/src/buildconfig.c | 31 ++++++++++++++++++--- src/src/deliver.c | 10 +++---- src/src/expand.c | 6 ++--- src/src/queue.c | 6 ++--- src/src/rda.c | 4 +-- src/src/string.c | 48 +++++++++++++++++++++++++++++---- src/src/tls-gnu.c | 6 ++--- src/src/transports/appendfile.c | 39 ++++++++++++++------------- src/src/transports/autoreply.c | 6 ++--- src/src/transports/tf_maildir.c | 23 ++++++++-------- 11 files changed, 130 insertions(+), 58 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 5ff2e8869..c377b9394 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -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 ----------------- diff --git a/src/src/buildconfig.c b/src/src/buildconfig.c index 46bf4738b..ee5e431a9 100644 --- a/src/src/buildconfig.c +++ b/src/src/buildconfig.c @@ -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 * @@ -15,8 +15,13 @@ /* 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) diff --git a/src/src/deliver.c b/src/src/deliver.c index c183c86ea..2568c9770 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -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); } } } diff --git a/src/src/expand.c b/src/src/expand.c index 0ae325946..7ecfc09d4 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -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; diff --git a/src/src/queue.c b/src/src/queue.c index a443fdfd0..f411f3629 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -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)); diff --git a/src/src/rda.c b/src/src/rda.c index 8f972ca4e..1be7b1cc4 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -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; diff --git a/src/src/string.c b/src/src/string.c index ba04aa471..aa4f93338 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -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; diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 723d97b4e..aedf09bc2 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -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. */ diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 6874fa746..b17eb3b39 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -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; diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 7c1af1509..e6a29318f 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -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" diff --git a/src/src/transports/tf_maildir.c b/src/src/transports/tf_maildir.c index 17f24d717..5277ef092 100644 --- a/src/src/transports/tf_maildir.c +++ b/src/src/transports/tf_maildir.c @@ -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; -- 2.25.1