static int
find_control(const uschar * name, control_def * ol, int last)
{
-int first = 0;
-while (last > first)
+for (int first = 0; last > first; )
{
int middle = (first + last)/2;
uschar * s = ol[middle].name;
static int
acl_checkcondition(uschar * name, condition_def * list, int end)
{
-int start = 0;
-while (start < end)
+for (int start = 0; start < end; )
{
int mid = (start + end)/2;
int c = Ustrcmp(name, list[mid].name);
static int
acl_checkname(uschar *name, uschar **list, int end)
{
-int start = 0;
-
-while (start < end)
+for (int start = 0; start < end; )
{
int mid = (start + end)/2;
int c = Ustrcmp(name, list[mid]);
acl_block *this = NULL;
acl_condition_block *cond;
acl_condition_block **condp = NULL;
-uschar *s;
+uschar * s;
*error = NULL;
fn_hdrs_added(void)
{
gstring * g = NULL;
-header_line * h;
-for (h = acl_added_headers; h; h = h->next)
+for (header_line * h = acl_added_headers; h; h = h->next)
{
int i = h->slen;
if (h->text[i-1] == '\n') i--;
/* Search previously logged warnings. They are kept in malloc
store so they can be freed at the start of a new message. */
- for (logged = acl_warn_logged; logged != NULL; logged = logged->next)
+ for (logged = acl_warn_logged; logged; logged = logged->next)
if (Ustrcmp(logged->text, text) == 0) break;
- if (logged == NULL)
+ if (!logged)
{
int length = Ustrlen(text) + 1;
log_write(0, LOG_MAIN, "%s", text);
/* If there's no user message, we are done. */
-if (user_message == NULL) return;
+if (!user_message) return;
/* If this isn't a message ACL, we can't do anything with a user message.
Log an error. */
if ((rc = host_name_lookup()) != OK)
{
- *log_msgptr = (rc == DEFER)?
- US"host lookup deferred for reverse lookup check"
- :
- string_sprintf("host lookup failed for reverse lookup check%s",
- host_lookup_msg);
+ *log_msgptr = rc == DEFER
+ ? US"host lookup deferred for reverse lookup check"
+ : string_sprintf("host lookup failed for reverse lookup check%s",
+ host_lookup_msg);
return rc; /* DEFER or FAIL */
}
acl_verify_csa_address(dns_answer *dnsa, dns_scan *dnss, int reset,
uschar *target)
{
-dns_record *rr;
-dns_address *da;
+int rc = CSA_FAIL_NOADDR;
-BOOL target_found = FALSE;
-
-for (rr = dns_next_rr(dnsa, dnss, reset);
- rr != NULL;
+for (dns_record * rr = dns_next_rr(dnsa, dnss, reset);
+ rr;
rr = dns_next_rr(dnsa, dnss, RESET_NEXT))
{
/* Check this is an address RR for the target hostname. */
if (strcmpic(target, rr->name) != 0) continue;
- target_found = TRUE;
+ rc = CSA_FAIL_MISMATCH;
/* Turn the target address RR into a list of textual IP addresses and scan
the list. There may be more than one if it is an A6 RR. */
- for (da = dns_address_from_rr(dnsa, rr); da != NULL; da = da->next)
+ for (dns_address * da = dns_address_from_rr(dnsa, rr); da; da = da->next)
{
/* If the client IP address matches the target IP address, it's good! */
using an unauthorized IP address, otherwise the target has no authorized IP
addresses. */
-if (target_found) return CSA_FAIL_MISMATCH;
-else return CSA_FAIL_NOADDR;
+return rc;
}
/* If we didn't break the loop then no appropriate records were found. */
-if (rr == NULL) return t->data.val = CSA_UNKNOWN;
+if (!rr) return t->data.val = CSA_UNKNOWN;
/* Do not check addresses if the target is ".", in accordance with RFC 2782.
A target of "." indicates there are no valid addresses, so the client cannot
/* Handle name/address consistency verification in a separate function. */
-for (vp= verify_type_list;
+for (vp = verify_type_list;
CS vp < CS verify_type_list + sizeof(verify_type_list);
vp++
)
/* We can test the result of optional HELO verification that might have
occurred earlier. If not, we can attempt the verification now. */
- if (!helo_verified && !helo_verify_failed) smtp_verify_helo();
- return helo_verified ? OK : FAIL;
+ if (!f.helo_verified && !f.helo_verify_failed) smtp_verify_helo();
+ return f.helo_verified ? OK : FAIL;
case VERIFY_CSA:
/* Do Client SMTP Authorization checks in a separate function, and turn the
/* Remaining items are optional; they apply to sender and recipient
verification, including "header sender" verification. */
-while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
- != NULL)
+while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
{
if (strcmpic(ss, US"defer_ok") == 0) defer_ok = TRUE;
else if (strcmpic(ss, US"no_details") == 0) no_details = TRUE;
{
const uschar * sublist = ss;
int optsep = ',';
- uschar *opt;
uschar buffer[256];
- while (isspace(*sublist)) sublist++;
+ uschar * opt;
+ while (isspace(*sublist)) sublist++;
while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer))))
{
callout_opt_t * op;
{
if (!*user_msgptr && *log_msgptr)
*user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr);
- if (rc == DEFER) acl_temp_details = TRUE;
+ if (rc == DEFER) f.acl_temp_details = TRUE;
}
}
}
addr2.user_message : addr2.message;
/* Allow details for temporary error if the address is so flagged. */
- if (testflag((&addr2), af_pass_message)) acl_temp_details = TRUE;
+ if (testflag((&addr2), af_pass_message)) f.acl_temp_details = TRUE;
/* Make $address_data visible */
deliver_address_data = addr2.prop.address_data;
log_msgptr for error messages
format format string
... supplementary arguments
- ss ratelimit option name
- where ACL_WHERE_xxxx indicating which ACL this is
Returns: ERROR
*/
ratelimit_error(uschar **log_msgptr, const char *format, ...)
{
va_list ap;
-uschar buffer[STRING_SPRINTF_BUFFER_SIZE];
+gstring * g =
+ string_cat(NULL, US"error in arguments to \"ratelimit\" condition: ");
+
va_start(ap, format);
-if (!string_vformat(buffer, sizeof(buffer), format, ap))
- log_write(0, LOG_MAIN|LOG_PANIC_DIE,
- "string_sprintf expansion was longer than " SIZE_T_FMT, sizeof(buffer));
+g = string_vformat(g, TRUE, format, ap);
va_end(ap);
-*log_msgptr = string_sprintf(
- "error in arguments to \"ratelimit\" condition: %s", buffer);
+
+gstring_reset_unused(g);
+*log_msgptr = string_from_gstring(g);
return ERROR;
}
arg = cb->arg;
else if (!(arg = expand_string(cb->arg)))
{
- if (expand_string_forcedfail) continue;
+ if (f.expand_string_forcedfail) continue;
*log_msgptr = string_sprintf("failed to expand ACL string \"%s\": %s",
cb->arg, expand_string_message);
- return search_find_defer ? DEFER : ERROR;
+ return f.search_find_defer ? DEFER : ERROR;
}
/* Show condition, and expanded condition if it's different */
switch(control_type)
{
case CONTROL_AUTH_UNADVERTISED:
- allow_auth_unadvertised = TRUE;
+ f.allow_auth_unadvertised = TRUE;
break;
#ifdef EXPERIMENTAL_BRIGHTMAIL
#ifndef DISABLE_DKIM
case CONTROL_DKIM_VERIFY:
- dkim_disable_verify = TRUE;
+ f.dkim_disable_verify = TRUE;
#ifdef EXPERIMENTAL_DMARC
/* Since DKIM was blocked, skip DMARC too */
- dmarc_disable_verify = TRUE;
- dmarc_enable_forensic = FALSE;
+ f.dmarc_disable_verify = TRUE;
+ f.dmarc_enable_forensic = FALSE;
#endif
break;
#endif
#ifdef EXPERIMENTAL_DMARC
case CONTROL_DMARC_VERIFY:
- dmarc_disable_verify = TRUE;
+ f.dmarc_disable_verify = TRUE;
break;
case CONTROL_DMARC_FORENSIC:
- dmarc_enable_forensic = TRUE;
+ f.dmarc_enable_forensic = TRUE;
break;
#endif
#ifdef WITH_CONTENT_SCAN
case CONTROL_NO_MBOX_UNSPOOL:
- no_mbox_unspool = TRUE;
+ f.no_mbox_unspool = TRUE;
break;
#endif
case CONTROL_NO_MULTILINE:
- no_multiline_responses = TRUE;
+ f.no_multiline_responses = TRUE;
break;
case CONTROL_NO_PIPELINING:
- pipelining_enable = FALSE;
+ f.pipelining_enable = FALSE;
break;
case CONTROL_NO_DELAY_FLUSH:
- disable_delay_flush = TRUE;
+ f.disable_delay_flush = TRUE;
break;
case CONTROL_NO_CALLOUT_FLUSH:
- disable_callout_flush = TRUE;
+ f.disable_callout_flush = TRUE;
break;
case CONTROL_FAKEREJECT:
if (*p == '/')
{
const uschar *pp = p + 1;
- while (*pp != 0) pp++;
+ while (*pp) pp++;
fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
p = pp;
}
break;
case CONTROL_FREEZE:
- deliver_freeze = TRUE;
+ f.deliver_freeze = TRUE;
deliver_frozen_at = time(NULL);
freeze_tell = freeze_tell_config; /* Reset to configured value */
if (Ustrncmp(p, "/no_tell", 8) == 0)
break;
case CONTROL_QUEUE_ONLY:
- queue_only_policy = TRUE;
+ f.queue_only_policy = TRUE;
cancel_cutthrough_connection(TRUE, US"queueing forced");
break;
#endif
case CONTROL_SUBMISSION:
originator_name = US"";
- submission_mode = TRUE;
+ f.submission_mode = TRUE;
while (*p == '/')
{
if (Ustrncmp(p, "/sender_retain", 14) == 0)
{
p += 14;
- active_local_sender_retain = TRUE;
- active_local_from_check = FALSE;
+ f.active_local_sender_retain = TRUE;
+ f.active_local_from_check = FALSE;
}
else if (Ustrncmp(p, "/domain=", 8) == 0)
{
const uschar *pp = p + 8;
- while (*pp != 0 && *pp != '/') pp++;
+ while (*pp && *pp != '/') pp++;
submission_domain = string_copyn(p+8, pp-p-8);
p = pp;
}
else if (Ustrncmp(p, "/name=", 6) == 0)
{
const uschar *pp = p + 6;
- while (*pp != 0) pp++;
+ while (*pp) pp++;
submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
big_buffer, big_buffer_size));
p = pp;
break;
case CONTROL_SUPPRESS_LOCAL_FIXUPS:
- suppress_local_fixups = TRUE;
+ f.suppress_local_fixups = TRUE;
break;
case CONTROL_CUTTHROUGH_DELIVERY:
ignored = US"PRDR active";
else
{
- if (deliver_freeze)
+ if (f.deliver_freeze)
ignored = US"frozen";
- else if (queue_only_policy)
+ else if (f.queue_only_policy)
ignored = US"queue-only";
else if (fake_response == FAIL)
ignored = US"fakereject";
else
{
- if (smtp_out != NULL && !disable_delay_flush)
+ if (smtp_out && !f.disable_delay_flush)
mac_smtp_fflush();
#if !defined(NO_POLL_H) && defined (POLLRDHUP)
HDEBUG(D_acl) debug_printf_indent("delay cancelled by peer close\n");
}
#else
- /* It appears to be impossible to detect that a TCP/IP connection has
- gone away without reading from it. This means that we cannot shorten
- the delay below if the client goes away, because we cannot discover
- that the client has closed its end of the connection. (The connection
- is actually in a half-closed state, waiting for the server to close its
- end.) It would be nice to be able to detect this state, so that the
- Exim process is not held up unnecessarily. However, it seems that we
- can't. The poll() function does not do the right thing, and in any case
- it is not always available.
- */
+ /* Lacking POLLRDHUP it appears to be impossible to detect that a
+ TCP/IP connection has gone away without reading from it. This means
+ that we cannot shorten the delay below if the client goes away,
+ because we cannot discover that the client has closed its end of the
+ connection. (The connection is actually in a half-closed state,
+ waiting for the server to close its end.) It would be nice to be able
+ to detect this state, so that the Exim process is not held up
+ unnecessarily. However, it seems that we can't. The poll() function
+ does not do the right thing, and in any case it is not always
+ available. */
while (delay > 0) delay = sleep(delay);
#endif
#ifdef EXPERIMENTAL_DMARC
case ACLC_DMARC_STATUS:
- if (!dmarc_has_been_checked)
+ if (!f.dmarc_has_been_checked)
dmarc_process();
- dmarc_has_been_checked = TRUE;
+ f.dmarc_has_been_checked = TRUE;
/* used long way of dmarc_exim_expand_query() in case we need more
* view into the process in the future. */
rc = match_isinlist(dmarc_exim_expand_query(DMARC_VERIFY_STATUS),
int logbits = 0;
int sep = 0;
const uschar *s = arg;
- uschar *ss;
+ uschar * ss;
while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)))
{
if (Ustrcmp(ss, "main") == 0) logbits |= LOG_MAIN;
}
while (isspace(*s)) s++;
-
if (logbits == 0) logbits = LOG_MAIN;
log_write(0, logbits, "%s", string_printing(s));
}
{
/* Separate the regular expression and any optional parameters. */
const uschar * list = arg;
- uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
- uschar *opt;
+ uschar * ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
+ uschar * opt;
BOOL defer_ok = FALSE;
int timeout = 0;
expmessage = expand_string(user_message);
if (!expmessage)
{
- if (!expand_string_forcedfail)
+ if (!f.expand_string_forcedfail)
log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand ACL message \"%s\": %s",
user_message, expand_string_message);
}
expmessage = expand_string(log_message);
if (!expmessage)
{
- if (!expand_string_forcedfail)
+ if (!f.expand_string_forcedfail)
log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand ACL message \"%s\": %s",
log_message, expand_string_message);
}
if (*acl_text == 0) return NULL; /* No more data */
yield = acl_text; /* Potential data line */
- while (*acl_text != 0 && *acl_text != '\n') acl_text++;
+ while (*acl_text && *acl_text != '\n') acl_text++;
/* If we hit the end before a newline, we have the whole logical line. If
it's a comment, there's no more data to be given. Otherwise, yield it. */
{
if (!(ss = expand_string(s)))
{
- if (expand_string_forcedfail) return OK;
+ if (f.expand_string_forcedfail) return OK;
*log_msgptr = string_sprintf("failed to expand ACL string \"%s\": %s", s,
expand_string_message);
return ERROR;
in the ACL tree, having read it into the POOL_PERM store pool so that it
persists between multiple messages. */
-if (acl == NULL)
+if (!acl)
{
int old_pool = store_pool;
if (fd >= 0) store_pool = POOL_PERM;
acl = acl_read(acl_getline, log_msgptr);
store_pool = old_pool;
- if (acl == NULL && *log_msgptr != NULL) return ERROR;
+ if (!acl && *log_msgptr) return ERROR;
if (fd >= 0)
{
tree_node *t = store_get_perm(sizeof(tree_node) + Ustrlen(ss));
/* Now we have an ACL to use. It's possible it may be NULL. */
-while (acl != NULL)
+while (acl)
{
int cond;
int basic_errno = 0;
&& (where == ACL_WHERE_QUIT || where == ACL_WHERE_NOTQUIT);
*log_msgptr = *user_msgptr = NULL;
- acl_temp_details = FALSE;
+ f.acl_temp_details = FALSE;
HDEBUG(D_acl) debug_printf_indent("processing \"%s\"\n", verbs[acl->verb]);
{
if (search_error_message != NULL && *search_error_message != 0)
*log_msgptr = search_error_message;
- if (smtp_return_error_details) acl_temp_details = TRUE;
+ if (smtp_return_error_details) f.acl_temp_details = TRUE;
}
else
- {
- acl_temp_details = TRUE;
- }
+ f.acl_temp_details = TRUE;
if (acl->verb != ACL_WARN) return DEFER;
break;
{
HDEBUG(D_acl) debug_printf_indent("end of %s: DEFER\n", acl_name);
if (acl_quit_check) goto badquit;
- acl_temp_details = TRUE;
+ f.acl_temp_details = TRUE;
return DEFER;
}
break;
return ret;
bad:
-if (expand_string_forcedfail) return ERROR;
+if (f.expand_string_forcedfail) return ERROR;
*log_msgptr = string_sprintf("failed to expand ACL string \"%s\": %s",
tmp, expand_string_message);
-return search_find_defer?DEFER:ERROR;
+return f.search_find_defer ? DEFER : ERROR;
}
case ACL_WHERE_PRDR:
#endif
- if (host_checking_callout) /* -bhc mode */
+ if (f.host_checking_callout) /* -bhc mode */
cancel_cutthrough_connection(TRUE, US"host-checking mode");
else if ( rc == OK
while (*s) s++;
do --s; while (!isdigit(*s));
if (*--s && isdigit(*s) && *--s && isdigit(*s)) *user_msgptr = s;
- acl_temp_details = TRUE;
+ f.acl_temp_details = TRUE;
}
else
{