if (!use_scan_command)
{ cmd_str.data = US"zINSTREAM"; cmd_str.len = 10; }
else
- {
- cmd_str.data = string_sprintf("SCAN %s\n", eml_filename);
- cmd_str.len = Ustrlen(cmd_str.data);
- }
+ cmd_str.data = string_sprintf("SCAN %s\n%n", eml_filename, &cmd_str.len);
/* We have some network servers specified */
if (num_servers)
on both connections (as one host could resolve to multiple ips) */
for (;;)
{
- /*XXX we trust that the cmd_str is ideempotent */
+ /*XXX we trust that the cmd_str is idempotent */
if ((malware_daemon_ctx.sock = m_tcpsocket(cd->hostspec, cd->tcp_port,
- &connhost, &errstr, &cmd_str)) >= 0)
+ &connhost, &errstr,
+ use_scan_command ? &cmd_str : NULL)) >= 0)
{
/* Connection successfully established with a server */
hostname = cd->hostspec;
- cmd_str.len = 0;
+ if (use_scan_command) cmd_str.len = 0;
break;
}
if (cd->retry <= 0) break;
if (!use_scan_command)
{
struct stat st;
-#ifdef EXIM_TCP_CORK
+#if defined(EXIM_TCP_CORK) && !defined(OS_SENDFILE)
BOOL corked = TRUE;
#endif
/* New protocol: "zINSTREAM\n" followed by a sequence of <length><data>
chunks, <n> a 4-byte number (network order), terminated by a zero-length
- chunk. */
+ chunk. We only send one chunk. */
DEBUG(D_acl) debug_printf_indent(
"Malware scan: issuing %s new-style remote scan (zINSTREAM)\n",
scanner_name);
+#if defined(EXIM_TCP_CORK)
+ (void) setsockopt(malware_daemon_ctx.sock, IPPROTO_TCP, EXIM_TCP_CORK,
+ US &on, sizeof(on));
+#endif
/* Pass the string to ClamAV (10 = "zINSTREAM\0"), if not already sent */
if (cmd_str.len)
if (send(malware_daemon_ctx.sock, cmd_str.data, cmd_str.len, 0) < 0)
}
/* send file size */
-#ifdef EXIM_TCP_CORK
- (void) setsockopt(malware_daemon_ctx.sock, IPPROTO_TCP, EXIM_TCP_CORK,
- US &on, sizeof(on));
-#endif
send_size = htonl(fsize_uint);
if (send(malware_daemon_ctx.sock, &send_size, sizeof(send_size), 0) < 0)
return m_panic_defer_3(scanent, NULL,
malware_daemon_ctx.sock);
/* send file body */
- /*XXX sendfile? */
while (fsize_uint)
{
- unsigned n = MIN(fsize_uint, big_buffer_size);
+#ifdef OS_SENDFILE
+ int n = os_sendfile(malware_daemon_ctx.sock, clam_fd, NULL, (size_t)fsize_uint);
+ if (n < 0)
+ return m_panic_defer_3(scanent, NULL,
+ string_sprintf("unable to send file body to socket (%s): %s", hostname, strerror(errno)),
+ malware_daemon_ctx.sock);
+ fsize_uint -= n;
+#else
+ int n = MIN(fsize_uint, big_buffer_size);
if ((n = read(clam_fd, big_buffer, n)) < 0)
return m_panic_defer_3(scanent, NULL,
string_sprintf("can't read spool file %s: %s",
string_sprintf("unable to send file body to socket (%s): %s", hostname, strerror(errno)),
malware_daemon_ctx.sock);
fsize_uint -= n;
-#ifdef EXIM_TCP_CORK
+# ifdef EXIM_TCP_CORK
if (corked)
{
corked = FALSE;
(void) setsockopt(malware_daemon_ctx.sock, IPPROTO_TCP, EXIM_TCP_CORK,
US &off, sizeof(off));
}
-#endif
+# endif
+#endif /*!OS_SENDFILE*/
+
}
send_final_zeroblock = 0;
return m_panic_defer_3(scanent, NULL,
string_sprintf("unable to send file terminator to socket (%s)", hostname),
malware_daemon_ctx.sock);
+#ifdef OS_SENDFILE
+ (void) setsockopt(malware_daemon_ctx.sock, IPPROTO_TCP, EXIM_TCP_CORK,
+ US &off, sizeof(off));
+#endif
}
else
{ /* use scan command */
/* Send a SCAN command pointing to a filename; then in the then in the
- * scan-method-neutral part, read the response back */
+ scan-method-neutral part, read the response back */
/* ================================================================= */