- save_errno = errno;
- goto CLEANUP;
- }
-
-/* Rewind file and feed it to the goats^W DKIM lib */
-dkim->dot_stuffed = !!(options & topt_end_dot);
-lseek(dkim_fd, 0, SEEK_SET);
-if ((dkim_signature = dkim_exim_sign(dkim_fd, dkim)))
- siglen = Ustrlen(dkim_signature);
-else if (dkim->dkim_strict)
- {
- uschar *dkim_strict_result = expand_string(dkim->dkim_strict);
- if (dkim_strict_result)
- if ( (strcmpic(dkim->dkim_strict,US"1") == 0) ||
- (strcmpic(dkim->dkim_strict,US"true") == 0) )
- {
- /* Set errno to something halfway meaningful */
- save_errno = EACCES;
- log_write(0, LOG_MAIN, "DKIM: message could not be signed,"
- " and dkim_strict is set. Deferring message delivery.");
- rc = FALSE;
- goto CLEANUP;
- }
- }
-
-#ifndef HAVE_LINUX_SENDFILE
-if (options & topt_use_bdat)
-#endif
- k_file_size = lseek(dkim_fd, 0, SEEK_END); /* Fetch file size */
-
-if (options & topt_use_bdat)
- {
-
- /* On big messages output a precursor chunk to get any pipelined
- MAIL & RCPT commands flushed, then reap the responses so we can
- error out on RCPT rejects before sending megabytes. */
-
- if (siglen + k_file_size > DELIVER_OUT_BUFFER_SIZE && siglen > 0)
- {
- if ( tctx->chunk_cb(out_fd, tctx, siglen, 0) != OK
- || !transport_write_block(out_fd, dkim_signature, siglen)
- || tctx->chunk_cb(out_fd, tctx, 0, tc_reap_prev) != OK
- )
- goto err;
- siglen = 0;
- }
-
- if (tctx->chunk_cb(out_fd, tctx, siglen + k_file_size, tc_chunk_last) != OK)
- goto err;
- }
-
-if(siglen > 0 && !transport_write_block(out_fd, dkim_signature, siglen))
- goto err;
-
-#ifdef HAVE_LINUX_SENDFILE
-/* We can use sendfile() to shove the file contents
- to the socket. However only if we don't use TLS,
- as then there's another layer of indirection
- before the data finally hits the socket. */
-if (tls_out.active != out_fd)
- {
- ssize_t copied = 0;
- off_t offset = 0;
-
- /* Rewind file */
- lseek(dkim_fd, 0, SEEK_SET);
-
- while(copied >= 0 && offset < k_file_size)
- copied = sendfile(out_fd, dkim_fd, &offset, k_file_size - offset);
- if (copied < 0)
- goto err;
- }
-else
-
-#endif
-
- {
- /* Rewind file */
- lseek(dkim_fd, 0, SEEK_SET);
-
- /* Send file down the original fd */
- while((sread = read(dkim_fd, deliver_out_buffer, DELIVER_OUT_BUFFER_SIZE)) >0)
- {
- uschar * p = deliver_out_buffer;
- /* write the chunk */
-
- while (sread)
- {
-#ifdef SUPPORT_TLS
- wwritten = tls_out.active == out_fd
- ? tls_write(FALSE, p, sread)
- : write(out_fd, CS p, sread);
-#else
- wwritten = write(out_fd, CS p, sread);
-#endif
- if (wwritten == -1)
- goto err;
- p += wwritten;
- sread -= wwritten;
- }
- }
-
- if (sread == -1)
- {
- save_errno = errno;
- rc = FALSE;
- }