-/* $Cambridge: exim/src/src/readconf.c,v 1.9 2005/05/24 08:15:02 tom Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.32 2007/08/22 10:10:23 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) University of Cambridge 1995 - 2007 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for reading the configuration file, and for displaying
#ifdef WITH_CONTENT_SCAN
{ "acl_not_smtp_mime", opt_stringptr, &acl_not_smtp_mime },
#endif
+ { "acl_not_smtp_start", opt_stringptr, &acl_not_smtp_start },
{ "acl_smtp_auth", opt_stringptr, &acl_smtp_auth },
{ "acl_smtp_connect", opt_stringptr, &acl_smtp_connect },
{ "acl_smtp_data", opt_stringptr, &acl_smtp_data },
#ifdef WITH_CONTENT_SCAN
{ "acl_smtp_mime", opt_stringptr, &acl_smtp_mime },
#endif
+ { "acl_smtp_notquit", opt_stringptr, &acl_smtp_notquit },
{ "acl_smtp_predata", opt_stringptr, &acl_smtp_predata },
{ "acl_smtp_quit", opt_stringptr, &acl_smtp_quit },
{ "acl_smtp_rcpt", opt_stringptr, &acl_smtp_rcpt },
{ "callout_random_local_part",opt_stringptr, &callout_random_local_part },
{ "check_log_inodes", opt_int, &check_log_inodes },
{ "check_log_space", opt_Kint, &check_log_space },
+ { "check_rfc2047_length", opt_bool, &check_rfc2047_length },
{ "check_spool_inodes", opt_int, &check_spool_inodes },
{ "check_spool_space", opt_Kint, &check_spool_space },
{ "daemon_smtp_port", opt_stringptr|opt_hidden, &daemon_smtp_port },
{ "daemon_smtp_ports", opt_stringptr, &daemon_smtp_port },
+ { "daemon_startup_retries", opt_int, &daemon_startup_retries },
+ { "daemon_startup_sleep", opt_time, &daemon_startup_sleep },
{ "delay_warning", opt_timelist, &delay_warning },
{ "delay_warning_condition", opt_stringptr, &delay_warning_condition },
{ "deliver_drop_privilege", opt_bool, &deliver_drop_privilege },
{ "deliver_queue_load_max", opt_fixed, &deliver_queue_load_max },
{ "delivery_date_remove", opt_bool, &delivery_date_remove },
+#ifdef ENABLE_DISABLE_FSYNC
+ { "disable_fsync", opt_bool, &disable_fsync },
+#endif
+ { "disable_ipv6", opt_bool, &disable_ipv6 },
{ "dns_again_means_nonexist", opt_stringptr, &dns_again_means_nonexist },
{ "dns_check_names_pattern", opt_stringptr, &check_dns_names_pattern },
{ "dns_csa_search_limit", opt_int, &dns_csa_search_limit },
/* This option is now a no-op, retained for compability */
{ "drop_cr", opt_bool, &drop_cr },
/*********************************************************/
+ { "dsn_from", opt_stringptr, &dsn_from },
{ "envelope_to_remove", opt_bool, &envelope_to_remove },
{ "errors_copy", opt_stringptr, &errors_copy },
{ "errors_reply_to", opt_stringptr, &errors_reply_to },
{ "freeze_tell", opt_stringptr, &freeze_tell },
{ "gecos_name", opt_stringptr, &gecos_name },
{ "gecos_pattern", opt_stringptr, &gecos_pattern },
+#ifdef SUPPORT_TLS
+ { "gnutls_require_kx", opt_stringptr, &gnutls_require_kx },
+ { "gnutls_require_mac", opt_stringptr, &gnutls_require_mac },
+ { "gnutls_require_protocols", opt_stringptr, &gnutls_require_proto },
+#endif
{ "header_line_maxsize", opt_int, &header_line_maxsize },
{ "header_maxsize", opt_int, &header_maxsize },
{ "headers_charset", opt_stringptr, &headers_charset },
{ "queue_only", opt_bool, &queue_only },
{ "queue_only_file", opt_stringptr, &queue_only_file },
{ "queue_only_load", opt_fixed, &queue_only_load },
+ { "queue_only_load_latch", opt_bool, &queue_only_load_latch },
{ "queue_only_override", opt_bool, &queue_only_override },
{ "queue_run_in_order", opt_bool, &queue_run_in_order },
{ "queue_run_max", opt_int, &queue_run_max },
#endif
{ "split_spool_directory", opt_bool, &split_spool_directory },
{ "spool_directory", opt_stringptr, &spool_directory },
+#ifdef LOOKUP_SQLITE
+ { "sqlite_lock_timeout", opt_int, &sqlite_lock_timeout },
+#endif
#ifdef EXPERIMENTAL_SRS
{ "srs_config", opt_stringptr, &srs_config },
{ "srs_hashlength", opt_int, &srs_hashlength },
{ "srs_usehash", opt_bool, &srs_usehash },
{ "srs_usetimestamp", opt_bool, &srs_usetimestamp },
#endif
+ { "strict_acl_vars", opt_bool, &strict_acl_vars },
{ "strip_excess_angle_brackets", opt_bool, &strip_excess_angle_brackets },
{ "strip_trailing_dot", opt_bool, &strip_trailing_dot },
{ "syslog_duplication", opt_bool, &syslog_duplication },
{
if (config_file_stack != NULL) /* EOF inside .include */
{
- fclose(config_file);
+ (void)fclose(config_file);
config_file = config_file_stack->file;
config_filename = config_file_stack->filename;
config_lineno = config_file_stack->lineno;
}
*t = 0;
+ if (*ss != '/')
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, ".include specifies a non-"
+ "absolute path \"%s\"", ss);
+
if (include_if_exists != 0 && (Ustat(ss, &statbuf) != 0)) continue;
save = store_get(sizeof(config_file_item));
int count = 1;
uid_t *list;
int ptr = 0;
- uschar *p = sptr;
+ uschar *p;
+ uschar *op = expand_string (sptr);
+
+ if (op == NULL)
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
+ name, expand_string_message);
+ p = op;
if (*p != 0) count++;
- while (*p != 0) if (*p++ == ':') count++;
+ while (*p != 0) if (*p++ == ':' && *p != 0) count++;
list = store_malloc(count*sizeof(uid_t));
list[ptr++] = (uid_t)(count - 1);
else
*((uid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
- p = sptr;
+ p = op;
while (count-- > 1)
{
int sep = 0;
int count = 1;
gid_t *list;
int ptr = 0;
- uschar *p = sptr;
+ uschar *p;
+ uschar *op = expand_string (sptr);
+
+ if (op == NULL)
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
+ name, expand_string_message);
+ p = op;
if (*p != 0) count++;
- while (*p != 0) if (*p++ == ':') count++;
+ while (*p != 0) if (*p++ == ':' && *p != 0) count++;
list = store_malloc(count*sizeof(gid_t));
list[ptr++] = (gid_t)(count - 1);
else
*((gid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
- p = sptr;
+ p = op;
while (count-- > 1)
{
int sep = 0;
case opt_int:
{
uschar *endptr;
+ long int lvalue;
+
errno = 0;
- value = strtol(CS s, CSS &endptr, intbase);
+ lvalue = strtol(CS s, CSS &endptr, intbase);
if (endptr == s)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
{
if (tolower(*endptr) == 'k')
{
- if (value > INT_MAX/1024 || value < INT_MIN/1024) errno = ERANGE;
- else value *= 1024;
+ if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE;
+ else lvalue *= 1024;
endptr++;
}
else if (tolower(*endptr) == 'm')
{
- if (value > INT_MAX/(1024*1024) || value < INT_MIN/(1024*1024))
+ if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024))
errno = ERANGE;
- else value *= 1024*1024;
+ else lvalue *= 1024*1024;
endptr++;
}
}
- if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
- "absolute value of integer \"%s\" is too large (overflow)", s);
+ 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)
extra_chars_error(endptr, inttype, US"integer value for ", name);
+
+ value = (int)lvalue;
}
if (data_block == NULL)
int s, m, h, d, w;
uschar *p = time_buffer;
+if (t < 0)
+ {
+ *p++ = '-';
+ t = -t;
+ }
+
s = t % 60;
t /= 60;
m = t % 60;
if (timezone_string != NULL && *timezone_string == 0) timezone_string = NULL;
+/* The max retry interval must not be greater than 24 hours. */
+
+if (retry_interval_max > 24*60*60) retry_interval_max = 24*60*60;
+
/* remote_max_parallel must be > 0 */
if (remote_max_parallel <= 0) remote_max_parallel = 1;
+/* Save the configured setting of freeze_tell, so we can re-instate it at the
+start of a new SMTP message. */
+
+freeze_tell_config = freeze_tell;
+
/* The primary host name may be required for expansion of spool_directory
and log_file_path, so make sure it is set asap. It is obtained from uname(),
but if that yields an unqualified value, make a FQDN by using gethostbyname to
struct hostent *hostdata;
#if HAVE_IPV6
- if (dns_ipv4_lookup == NULL ||
+ if (!disable_ipv6 && (dns_ipv4_lookup == NULL ||
match_isinlist(hostname, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
- TRUE, NULL) != OK)
+ TRUE, NULL) != OK))
af = AF_INET6;
#else
af = AF_INET;
}
}
-else if (strncmpic(pp, US"rcpt_4", 6) == 0)
+else if (strncmpic(pp, US"mail_4", 6) == 0 ||
+ strncmpic(pp, US"rcpt_4", 6) == 0 ||
+ strncmpic(pp, US"data_4", 6) == 0)
{
BOOL bad = FALSE;
int x = 255; /* means "any 4xx code" */
else if (a != 'x' || b != 'x') bad = TRUE;
}
- if (bad) return US"rcpt_4 must be followed by xx, dx, or dd, where "
- "x is literal and d is any digit";
+ if (bad)
+ return string_sprintf("%.4s_4 must be followed by xx, dx, or dd, where "
+ "x is literal and d is any digit", pp);
- *basic_errno = ERRNO_RCPT4XX;
+ *basic_errno = (*pp == 'm')? ERRNO_MAIL4XX :
+ (*pp == 'r')? ERRNO_RCPT4XX : ERRNO_DATA4XX;
*more_errno = x << 8;
}
else if (len == 4 && strncmpic(pp, US"auth", len) == 0 &&
strncmpic(q+1, US"failed", p-q-1) == 0)
- {
*basic_errno = ERRNO_AUTHFAIL;
- }
+
+else if (strncmpic(pp, US"lost_connection", p - pp) == 0)
+ *basic_errno = ERRNO_SMTPCLOSED;
+
+else if (strncmpic(pp, US"tls_required", p - pp) == 0)
+ *basic_errno = ERRNO_TLSREQUIRED;
else if (len != 1 || Ustrncmp(pp, "*", 1) != 0)
return string_sprintf("unknown or malformed retry error \"%.*s\"", p-pp, pp);
break;
case 'G': /* Geometrically increasing intervals */
+ case 'H': /* Ditto, but with randomness */
rule->p1 = retry_arg(&p, 0);
rule->p2 = retry_arg(&p, 1);
break;
}
if (rule->timeout <= 0 || rule->p1 <= 0 ||
- (rule->rule == 'G' && rule->p2 < 1000))
+ (rule->rule != 'F' && rule->p2 < 1000))
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
"bad parameters for retry rule");
}
}
-fclose(config_file);
+(void)fclose(config_file);
}
/* End of readconf.c */