+/*************************************************
+* Recheck synchronization *
+*************************************************/
+
+/* Synchronization checks can never be perfect because a packet may be on its
+way but not arrived when the check is done. Such checks can in any case only be
+done when TLS is not in use. Normally, the checks happen when commands are
+read: Exim ensures that there is no more input in the input buffer. In normal
+cases, the response to the command will be fast, and there is no further check.
+
+However, for some commands an ACL is run, and that can include delays. In those
+cases, it is useful to do another check on the input just before sending the
+response. This also applies at the start of a connection. This function does
+that check by means of the select() function, as long as the facility is not
+disabled or inappropriate. A failure of select() is ignored.
+
+When there is unwanted input, we read it so that it appears in the log of the
+error.
+
+Arguments: none
+Returns: TRUE if all is well; FALSE if there is input pending
+*/
+
+static BOOL
+check_sync(void)
+{
+int fd, rc;
+fd_set fds;
+struct timeval tzero;
+
+if (!smtp_enforce_sync || sender_host_address == NULL ||
+ sender_host_notsocket || tls_in.active >= 0)
+ return TRUE;
+
+fd = fileno(smtp_in);
+FD_ZERO(&fds);
+FD_SET(fd, &fds);
+tzero.tv_sec = 0;
+tzero.tv_usec = 0;
+rc = select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tzero);
+
+if (rc <= 0) return TRUE; /* Not ready to read */
+rc = smtp_getc(GETC_BUFFER_UNLIMITED);
+if (rc < 0) return TRUE; /* End of file or error */
+
+smtp_ungetc(rc);
+rc = smtp_inend - smtp_inptr;
+if (rc > 150) rc = 150;
+smtp_inptr[rc] = 0;
+return FALSE;
+}
+
+
+
+/*************************************************
+* Log incomplete transactions *
+*************************************************/
+
+/* This function is called after a transaction has been aborted by RSET, QUIT,
+connection drops or other errors. It logs the envelope information received
+so far in order to preserve address verification attempts.
+
+Argument: string to indicate what aborted the transaction
+Returns: nothing
+*/
+
+static void
+incomplete_transaction_log(uschar *what)
+{
+if (sender_address == NULL || /* No transaction in progress */
+ !LOGGING(smtp_incomplete_transaction))
+ return;
+
+/* Build list of recipients for logging */
+
+if (recipients_count > 0)
+ {
+ int i;
+ raw_recipients = store_get(recipients_count * sizeof(uschar *));
+ for (i = 0; i < recipients_count; i++)
+ raw_recipients[i] = recipients_list[i].address;
+ raw_recipients_count = recipients_count;
+ }
+
+log_write(L_smtp_incomplete_transaction, LOG_MAIN|LOG_SENDER|LOG_RECIPIENTS,
+ "%s incomplete transaction (%s)", host_and_ident(TRUE), what);
+}
+
+
+
+