* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2012 */
/* See the file NOTICE for conditions of use and distribution. */
/* local_scan()) */
vtype_todbsdin, /* value not used; generate BSD inbox tod */
vtype_tode, /* value not used; generate tod in epoch format */
+ vtype_todel, /* value not used; generate tod in epoch/usec format */
vtype_todf, /* value not used; generate full tod */
vtype_todl, /* value not used; generate log tod */
vtype_todlf, /* value not used; generate log file datestamp tod */
{ "tls_certificate_verified", vtype_int, &tls_certificate_verified },
{ "tls_cipher", vtype_stringptr, &tls_cipher },
{ "tls_peerdn", vtype_stringptr, &tls_peerdn },
-#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
+#ifdef SUPPORT_TLS
{ "tls_sni", vtype_stringptr, &tls_sni },
#endif
{ "tod_bsdinbox", vtype_todbsdin, NULL },
{ "tod_epoch", vtype_tode, NULL },
+ { "tod_epoch_l", vtype_todel, NULL },
{ "tod_full", vtype_todf, NULL },
{ "tod_log", vtype_todl, NULL },
{ "tod_logfile", vtype_todlf, NULL },
+
/*************************************************
* Pseudo-random number generation *
*************************************************/
However, if we're stuck unable to provide this, then we'll fall back to
appallingly bad randomness.
-If SUPPORT_TLS is defined and OpenSSL is used, then this will not be used.
-The GNUTLS randomness functions found do not seem amenable to extracting
-random numbers outside of a TLS context. Any volunteers?
+If SUPPORT_TLS is defined then this will not be used except as an emergency
+fallback.
Arguments:
max range maximum
Returns a random number in range [0, max-1]
*/
-#if !defined(SUPPORT_TLS) || defined(USE_GNUTLS)
+#ifdef SUPPORT_TLS
+# define vaguely_random_number vaguely_random_number_fallback
+#endif
int
-pseudo_random_number(int max)
+vaguely_random_number(int max)
{
+#ifdef SUPPORT_TLS
+# undef vaguely_random_number
+#endif
static pid_t pid = 0;
pid_t p2;
#if defined(HAVE_SRANDOM) && !defined(HAVE_SRANDOMDEV)
#endif
}
-#endif
+
+
/*************************************************
* Pick out a name from a string *
domain = Ustrrchr(s, '@');
if (domain == NULL) return s;
if (domain - s > sizeof(var_buffer) - 1)
- log_write(0, LOG_MAIN|LOG_PANIC_DIE, "local part longer than %d in "
- "string expansion", sizeof(var_buffer));
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "local part longer than " SIZE_T_FMT
+ " in string expansion", sizeof(var_buffer));
Ustrncpy(var_buffer, s, domain - s);
var_buffer[domain - s] = 0;
return var_buffer;
case vtype_tode: /* Unix epoch time of day */
return tod_stamp(tod_epoch);
+ case vtype_todel: /* Unix epoch/usec time of day */
+ return tod_stamp(tod_epoch_l);
+
case vtype_todf: /* Full time of day */
return tod_stamp(tod_full);
BOOL *subcondptr;
BOOL sub2_honour_dollar = TRUE;
int i, rc, cond_type, roffset;
-int64_t num[2];
+int_eximarith_t num[2];
struct stat statbuf;
uschar name[256];
uschar *sub[4];
on failure: an undefined value, with *error = a message
*/
-static int64_t eval_op_or(uschar **, BOOL, uschar **);
+static int_eximarith_t eval_op_or(uschar **, BOOL, uschar **);
-static int64_t
+static int_eximarith_t
eval_expr(uschar **sptr, BOOL decimal, uschar **error, BOOL endket)
{
uschar *s = *sptr;
-int64_t x = eval_op_or(&s, decimal, error);
+int_eximarith_t x = eval_op_or(&s, decimal, error);
if (*error == NULL)
{
if (endket)
}
-static int64_t
+static int_eximarith_t
eval_number(uschar **sptr, BOOL decimal, uschar **error)
{
register int c;
-int64_t n;
+int_eximarith_t n;
uschar *s = *sptr;
while (isspace(*s)) s++;
c = *s;
if (isdigit(c))
{
int count;
- (void)sscanf(CS s, (decimal? "%lld%n" : "%lli%n"), &n, &count);
+ (void)sscanf(CS s, (decimal? SC_EXIM_DEC "%n" : SC_EXIM_ARITH "%n"), &n, &count);
s += count;
- if (tolower(*s) == 'k') { n *= 1024; s++; }
- else if (tolower(*s) == 'm') { n *= 1024*1024; s++; }
+ switch (tolower(*s))
+ {
+ default: break;
+ case 'k': n *= 1024; s++; break;
+ case 'm': n *= 1024*1024; s++; break;
+ case 'g': n *= 1024*1024*1024; s++; break;
+ }
while (isspace (*s)) s++;
}
else if (c == '(')
}
-static int64_t
+static int_eximarith_t
eval_op_unary(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
-int64_t x;
+int_eximarith_t x;
while (isspace(*s)) s++;
if (*s == '+' || *s == '-' || *s == '~')
{
}
-static int64_t
+static int_eximarith_t
eval_op_mult(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
-int64_t x = eval_op_unary(&s, decimal, error);
+int_eximarith_t x = eval_op_unary(&s, decimal, error);
if (*error == NULL)
{
while (*s == '*' || *s == '/' || *s == '%')
{
int op = *s++;
- int64_t y = eval_op_unary(&s, decimal, error);
+ int_eximarith_t y = eval_op_unary(&s, decimal, error);
if (*error != NULL) break;
/* SIGFPE both on div/mod by zero and on INT_MIN / -1, which would give
* a value of INT_MAX+1. Note that INT_MIN * -1 gives INT_MIN for me, which
if (y == -1 && x == LLONG_MIN && op != '*')
{
DEBUG(D_expand)
- debug_printf("Integer exception dodging: %lld%c-1 coerced to %lld\n",
+ debug_printf("Integer exception dodging: " PR_EXIM_ARITH "%c-1 coerced to " PR_EXIM_ARITH "\n",
LLONG_MIN, op, LLONG_MAX);
x = LLONG_MAX;
continue;
}
-static int64_t
+static int_eximarith_t
eval_op_sum(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
-int64_t x = eval_op_mult(&s, decimal, error);
+int_eximarith_t x = eval_op_mult(&s, decimal, error);
if (*error == NULL)
{
while (*s == '+' || *s == '-')
{
int op = *s++;
- int64_t y = eval_op_mult(&s, decimal, error);
+ int_eximarith_t y = eval_op_mult(&s, decimal, error);
if (*error != NULL) break;
if (op == '+') x += y; else x -= y;
}
}
-static int64_t
+static int_eximarith_t
eval_op_shift(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
-int64_t x = eval_op_sum(&s, decimal, error);
+int_eximarith_t x = eval_op_sum(&s, decimal, error);
if (*error == NULL)
{
while ((*s == '<' || *s == '>') && s[1] == s[0])
{
- int64_t y;
+ int_eximarith_t y;
int op = *s++;
s++;
y = eval_op_sum(&s, decimal, error);
}
-static int64_t
+static int_eximarith_t
eval_op_and(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
-int64_t x = eval_op_shift(&s, decimal, error);
+int_eximarith_t x = eval_op_shift(&s, decimal, error);
if (*error == NULL)
{
while (*s == '&')
{
- int64_t y;
+ int_eximarith_t y;
s++;
y = eval_op_shift(&s, decimal, error);
if (*error != NULL) break;
}
-static int64_t
+static int_eximarith_t
eval_op_xor(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
-int64_t x = eval_op_and(&s, decimal, error);
+int_eximarith_t x = eval_op_and(&s, decimal, error);
if (*error == NULL)
{
while (*s == '^')
{
- int64_t y;
+ int_eximarith_t y;
s++;
y = eval_op_and(&s, decimal, error);
if (*error != NULL) break;
}
-static int64_t
+static int_eximarith_t
eval_op_or(uschar **sptr, BOOL decimal, uschar **error)
{
uschar *s = *sptr;
-int64_t x = eval_op_xor(&s, decimal, error);
+int_eximarith_t x = eval_op_xor(&s, decimal, error);
if (*error == NULL)
{
while (*s == '|')
{
- int64_t y;
+ int_eximarith_t y;
s++;
y = eval_op_xor(&s, decimal, error);
if (*error != NULL) break;
{
uschar *save_sub = sub;
uschar *error = NULL;
- int64_t n = eval_expr(&sub, (c == EOP_EVAL10), &error, FALSE);
+ int_eximarith_t n = eval_expr(&sub, (c == EOP_EVAL10), &error, FALSE);
if (error != NULL)
{
expand_string_message = string_sprintf("error in expression "
save_sub);
goto EXPAND_FAILED;
}
- sprintf(CS var_buffer, "%lld", n);
+ sprintf(CS var_buffer, PR_EXIM_ARITH, n);
yield = string_cat(yield, &size, &ptr, var_buffer, Ustrlen(var_buffer));
continue;
}
continue;
}
- /* pseudo-random number less than N */
+ /* vaguely random number less than N */
case EOP_RANDINT:
{
- int64_t max;
+ int_eximarith_t max;
uschar *s;
max = expand_string_integer(sub, TRUE);
if (expand_string_message != NULL)
goto EXPAND_FAILED;
- s = string_sprintf("%d", pseudo_random_number((int)max));
+ s = string_sprintf("%d", vaguely_random_number((int)max));
yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
continue;
}
expand_string_message is set NULL for an OK integer
*/
-int64_t
+int_eximarith_t
expand_string_integer(uschar *string, BOOL isplus)
{
-int64_t value;
+int_eximarith_t value;
uschar *s = expand_string(string);
uschar *msg = US"invalid integer \"%s\"";
uschar *endptr;