+
+ if (strcmpic(clamd_options2,US"local") == 0) {
+
+ /* Pass the string to ClamAV (7 = "SCAN \n" + \0) */
+
+ snprintf(CS file_name,1024,"SCAN %s/scan/%s\n", spool_directory, message_id);
+
+ if (send(sock, file_name, Ustrlen(file_name), 0) < 0) {
+ close(sock);
+ log_write(0, LOG_MAIN|LOG_PANIC,"malware acl condition: clamd: unable to write to socket (%s)",
+ strerror(errno));
+ return DEFER;
+ }
+ } else {
+
+ /* Pass the string to ClamAV (7 = "STREAM\n") */
+
+ if (send(sock, "STREAM\n", 7, 0) < 0) {
+ close(sock);
+ log_write(0, LOG_MAIN|LOG_PANIC,"malware acl condition: clamd: unable to write to socket (%s)",
+ strerror(errno));
+ return DEFER;
+ }
+ memset(av_buffer2, 0, sizeof(av_buffer2));
+ bread = read(sock, av_buffer2, sizeof(av_buffer2));
+
+ if (bread < 0) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: unable to read PORT from socket (%s)",
+ strerror(errno));
+ return DEFER;
+ }
+
+ if (bread == sizeof(av_buffer)) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: buffer too small");
+ return DEFER;
+ }
+
+ if (!(*av_buffer2)) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: ClamAV returned null");
+ return DEFER;
+ }
+
+ av_buffer2[bread] = '\0';
+ if( sscanf(CS av_buffer2, "PORT %hu\n", &port) != 1 ) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: Expected port information from clamd, got '%s'", av_buffer2);
+ return DEFER;
+ };
+
+ if ( (sockData = ip_socket(SOCK_STREAM, AF_INET)) < 0) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: unable to acquire socket (%s)",
+ strerror(errno));
+ return DEFER;
+ }
+
+ if (ip_connect(sockData, AF_INET, (uschar*)inet_ntoa(in), port, 5) < 0) {
+ close(sockData);
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: connection to %s, port %u failed (%s)",
+ inet_ntoa(in), port, strerror(errno));
+ return DEFER;
+ }
+
+ snprintf(CS scanrequest, 1024,CS"%s/scan/%s/%s.eml",
+ spool_directory, message_id, message_id);
+
+ /* calc file size */
+ clam_fd = open(CS scanrequest, O_RDONLY);
+ if (clam_fd == -1) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: can't open spool file %s: %s",
+ scanrequest, strerror(errno));
+ return DEFER;
+ }
+ fsize = lseek(clam_fd, 0, SEEK_END);
+ if (fsize == -1) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: can't seek spool file %s: %s",
+ scanrequest, strerror(errno));
+ return DEFER;
+ }
+ lseek(clam_fd, 0, SEEK_SET);
+
+ clamav_fbuf = (uschar *) malloc (fsize);
+ if (!clamav_fbuf) {
+ close(sockData);
+ close(clam_fd);
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: unable to allocate memory %u for file (%s)",
+ fsize, scanrequest);
+ return DEFER;
+ }
+
+ result = read (clam_fd, clamav_fbuf, fsize);
+ if (result == -1) {
+ close(sockData);
+ close(clam_fd);
+ free(clamav_fbuf);
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: can't read spool file %s: %s",
+ scanrequest, strerror(errno));
+ return DEFER;
+ }
+ close(clam_fd);
+
+ /* send file body to socket */
+ if (send(sockData, clamav_fbuf, fsize, 0) < 0) {
+ close(sockData);
+ free(clamav_fbuf);
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "malware acl condition: clamd: unable to send file body to socket (%s:%u)", hostname, port);
+ return DEFER;
+ }
+ free(clamav_fbuf);
+ close(sockData);
+ }