+
+/* Callback for emitting a BDAT data chunk header.
+Flush any buffered SMTP commands first.
+Reap SMTP command responses if not the BDAT LAST.
+
+A nonlast request that is size zero is special-cased to only flush the
+command buffer and reap all outstanding responses.
+
+Returns: OK or ERROR
+*/
+
+static int
+smtp_chunk_cmd_callback(int fd, transport_ctx * tctx,
+ unsigned chunk_size, BOOL chunk_last)
+{
+smtp_transport_options_block * ob =
+ (smtp_transport_options_block *)(tctx->tblock->options_block);
+uschar buffer[128];
+
+if ( (tctx->cmd_count = chunk_size == 0 && !chunk_last
+
+ /* Handle flush request */
+ ? smtp_write_command(tctx->outblock, FALSE, NULL)
+
+ /* Write SMTP chunk header command */
+ : smtp_write_command(tctx->outblock, FALSE, "BDAT %u%s\r\n",
+ chunk_size, chunk_last ? " LAST" : "")
+ )
+ < 0)
+ return ERROR;
+
+if (chunk_last)
+ return OK;
+
+/* Reap responses for this and any previous, and error out on failure */
+debug_printf("(look for %d responses)\n", tctx->cmd_count);
+
+switch(sync_responses(tctx->first_addr, tctx->tblock->rcpt_include_affixes,
+ tctx->sync_addr, tctx->host, tctx->cmd_count,
+ ob->address_retry_include_sender,
+ tctx->pending_MAIL, 0,
+ tctx->inblock,
+ ob->command_timeout,
+ buffer, sizeof(buffer)))
+ {
+ case 1: /* 2xx (only) => OK */
+ case 3: /* 2xx & 5xx => OK & progress made */
+ case 2: *tctx->completed_address = TRUE; /* 5xx (only) => progress made */
+ case 0: return OK; /* No 2xx or 5xx, but no probs */
+
+ case -1: /* Timeout on RCPT */
+ default: return ERROR; /* I/O error, or any MAIL/DATA error */
+ }
+}
+
+
+