enum { CALLOUT_DEFER_OK, CALLOUT_NOCACHE, CALLOUT_RANDOM, CALLOUT_USE_SENDER,
CALLOUT_USE_POSTMASTER, CALLOUT_POSTMASTER, CALLOUT_FULLPOSTMASTER,
CALLOUT_MAILFROM, CALLOUT_POSTMASTER_MAILFROM, CALLOUT_MAXWAIT, CALLOUT_CONNECT,
- CALLOUT_TIME
+ CALLOUT_HOLD, CALLOUT_TIME /* TIME must be last */
};
typedef struct {
uschar * name;
{ US"mailfrom", CALLOUT_MAILFROM, 0, TRUE, FALSE },
{ US"maxwait", CALLOUT_MAXWAIT, 0, TRUE, TRUE },
{ US"connect", CALLOUT_CONNECT, 0, TRUE, TRUE },
+ { US"hold", CALLOUT_HOLD, vopt_callout_hold, FALSE, FALSE },
{ NULL, CALLOUT_TIME, 0, FALSE, TRUE }
};
uschar buffer[256];
while (isspace(*sublist)) sublist++;
- while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer)))
- != NULL)
+ while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer))))
{
callout_opt_t * op;
double period = 1.0F;
}
while (isspace(*opt)) opt++;
}
- if (op->timeval)
+ if (op->timeval && (period = readconf_readtime(opt, 0, FALSE)) < 0)
{
- period = readconf_readtime(opt, 0, FALSE);
- if (period < 0)
- {
- *log_msgptr = string_sprintf("bad time value in ACL condition "
- "\"verify %s\"", arg);
- return ERROR;
- }
+ *log_msgptr = string_sprintf("bad time value in ACL condition "
+ "\"verify %s\"", arg);
+ return ERROR;
}
switch(op->value)
break;
case CONTROL_FAKEREJECT:
- cancel_cutthrough_connection("fakereject");
+ cancel_cutthrough_connection(TRUE, US"fakereject");
case CONTROL_FAKEDEFER:
fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
if (*p == '/')
*log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
return ERROR;
}
- cancel_cutthrough_connection("item frozen");
+ cancel_cutthrough_connection(TRUE, US"item frozen");
break;
case CONTROL_QUEUE_ONLY:
queue_only_policy = TRUE;
- cancel_cutthrough_connection("queueing forced");
+ cancel_cutthrough_connection(TRUE, US"queueing forced");
break;
case CONTROL_SUBMISSION:
#ifndef DISABLE_PRDR
case ACL_WHERE_PRDR:
#endif
+
if (host_checking_callout) /* -bhc mode */
- cancel_cutthrough_connection("host-checking mode");
+ cancel_cutthrough_connection(TRUE, US"host-checking mode");
else if ( rc == OK
&& cutthrough.delivery
if (rc == OK)
cutthrough_predata();
else
- cancel_cutthrough_connection("predata acl not ok");
+ cancel_cutthrough_connection(TRUE, US"predata acl not ok");
break;
case ACL_WHERE_QUIT:
case ACL_WHERE_NOTQUIT:
- cancel_cutthrough_connection("quit or notquit");
+ /* Drop cutthrough conns, and drop heldopen verify conns if
+ the previous was not DATA */
+ {
+ uschar prev = smtp_connection_had[smtp_ch_index-2];
+ BOOL dropverify = !(prev == SCH_DATA || prev == SCH_BDAT);
+
+ cancel_cutthrough_connection(dropverify, US"quit or conndrop");
break;
+ }
default:
break;