-/*
-Copyright (c) 2013-2015, Alexey Savelyev <info@homeweb.ru>
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Based on source code from http://www.ols.es/exim/dlext/ by David Saez <david@ols.es>,
-source code of exim by Philip Hazel <ph10@cam.ac.uk>
-and source code of exiscan by Tom Kistner <tom@duncanthrax.net>
-and source code of Victor Ustugov http://mta.org.ua/
+/*-
+ * Copyright (c) 2013-2015, Alexey Savelyev <info@homeweb.ru>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * Based on source code from http://www.ols.es/exim/dlext/ by David Saez <david@ols.es>,
+ * source code of exim by Philip Hazel <ph10@cam.ac.uk>
+ * and source code of exiscan by Tom Kistner <tom@duncanthrax.net>
+ * and source code of Victor Ustugov http://mta.org.ua/
*/
#include "exim.h"
#include "cJSON.h"
#include "cJSON.c"
-#define RSPAMD_TIMEOUT 120
+#define RSPAMD_TIMEOUT 120
-extern uschar *tod_stamp(int);
+extern uschar *tod_stamp (int);
//extern BOOL split_spool_directory; /* TRUE to use multiple subdirs */
//extern uschar *spool_directory; /* Name of spool directory */
//extern uschar message_subdir[]; /* Subdirectory for messages */
//-------------------------------------------------------------------------
-int strpos(char *hay, char *needle, int offset)
+int
+strpos (char *hay, char *needle, int offset)
{
- char haystack[strlen(hay)];
- strncpy(haystack, hay+offset, strlen(hay)-offset);
- char *p = strstr(haystack, needle);
- if (p)
- return p - haystack+offset;
- return -1;
+ char haystack[strlen (hay)];
+ strncpy (haystack, hay + offset, strlen (hay) - offset);
+ char *p = strstr (haystack, needle);
+ if (p)
+ return p - haystack + offset;
+ return -1;
}
-int rspamd(uschar **yield, int argc, uschar *argv[]) {
- char *arg_socket_addr;
- char *arg_defer_ok;
- int defer_ok;
- int rspamd_command;
- char tcp_addr[15];
- int tcp_port;
- FILE *mbox_file = NULL;
+int
+rspamd (uschar **yield, int argc, uschar *argv[])
+{
+ char *arg_socket_addr;
+ char *arg_defer_ok;
+ int defer_ok;
+ int rspamd_command;
+ char tcp_addr[15];
+ int tcp_port;
+ FILE *mbox_file = NULL;
// unsigned long mbox_size;
- off_t mbox_size;
- uschar *s, *p;
- header_line *my_header, *header_new, *header_last, *tmp_headerlist;
- header_line *last_received = NULL;
- uschar *address;
- uschar *helo;
- uschar *sender_host_name;
- uschar *authenticated_id;
- char mbox_path[512];
- int max_len, len;
- int rspamd_sock = 0;
- struct hostent *he;
- struct in_addr in;
- struct sockaddr_un server;
+ off_t mbox_size;
+ uschar *s, *p;
+ header_line *my_header, *header_new, *header_last, *tmp_headerlist;
+ header_line *last_received = NULL;
+ uschar *address;
+ uschar *helo;
+ uschar *sender_host_name;
+ uschar *authenticated_id;
+ char mbox_path[512];
+ int max_len, len;
+ int rspamd_sock = 0;
+ struct hostent *he;
+ struct in_addr in;
+ struct sockaddr_un server;
#ifndef NO_POLL_H
- int result;
- struct pollfd pollfd;
+ int result;
+ struct pollfd pollfd;
#endif
- int offset;
- uschar spamd_buffer[32600];
- uschar spamd_buffer2[32600];
- time_t start;
- size_t read, wrote;
- int i, j, c;
-
- arg_socket_addr = argv[0];
- arg_defer_ok = argv[1];
-
- if (argc < 2) {
- defer_ok = 0;
- } else if (
- (strcmpic(arg_defer_ok,US"1") == 0)
- || (strcmpic(arg_defer_ok,US"yes") == 0)
- || (strcmpic(arg_defer_ok,US"true") == 0)
- || (strcmpic(arg_defer_ok,US"defer_ok") == 0)
+ int offset;
+ uschar spamd_buffer[32600];
+ uschar spamd_buffer2[32600];
+ time_t start;
+ size_t read, wrote;
+ int i, j, c;
+
+ arg_socket_addr = argv[0];
+ arg_defer_ok = argv[1];
+
+ if (argc < 2) {
+ defer_ok = 0;
+ } else if (
+ (strcmpic (arg_defer_ok, US
+ "1") == 0)
+ || (strcmpic (arg_defer_ok, US
+ "yes") == 0)
+ || (strcmpic (arg_defer_ok, US
+ "true") == 0)
+ || (strcmpic (arg_defer_ok, US
+ "defer_ok") == 0)
) {
- defer_ok = 1;
- } else {
- defer_ok = 0;
- }
+ defer_ok = 1;
+ } else {
+ defer_ok = 0;
+ }
//debug_printf(" defer_ok: %d\n", defer_ok);
- if ((arg_socket_addr == NULL) || (arg_socket_addr[0] == 0)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: Socket address expected");
- *yield = string_sprintf("rspamd dlfunc: Socket address expected");
- goto RETURN_DEFER;
- }
+ if ((arg_socket_addr == NULL) || (arg_socket_addr[0] == 0)) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: Socket address expected");
+ *yield = string_sprintf ("rspamd dlfunc: Socket address expected");
+ goto RETURN_DEFER;
+ }
// get message body stream
- if (split_spool_directory == 0) {
- sprintf(mbox_path, "%s/input/%s-D", spool_directory, message_id);
- } else {
- sprintf(mbox_path, "%s/input/%s/%s-D", spool_directory, message_subdir, message_id);
- }
+ if (split_spool_directory == 0) {
+ sprintf (mbox_path, "%s/input/%s-D", spool_directory, message_id);
+ } else {
+ sprintf (mbox_path, "%s/input/%s/%s-D", spool_directory, message_subdir,
+ message_id);
+ }
//debug_printf(" Open spool file: %s\n", mbox_path);
- mbox_file = fopen(mbox_path,"rb");
+ mbox_file = fopen (mbox_path, "rb");
- if (!mbox_file) {
- *yield = string_sprintf("rspamd dlfunc: Unable to spool message '%s'", mbox_path);
- return(defer_ok ? OK : ERROR);
- }
+ if (!mbox_file) {
+ *yield = string_sprintf ("rspamd dlfunc: Unable to spool message '%s'",
+ mbox_path);
+ return (defer_ok ? OK : ERROR);
+ }
- (void)fseek(mbox_file, 0, SEEK_END);
- mbox_size = ftell(mbox_file);
+ (void) fseek (mbox_file, 0, SEEK_END);
+ mbox_size = ftell (mbox_file);
//debug_printf(" Total spool file size: %d\n", mbox_size);
- mbox_size -= SPOOL_DATA_START_OFFSET;
+ mbox_size -= SPOOL_DATA_START_OFFSET;
//debug_printf(" Spool file size: %d\n", mbox_size);
//debug_printf(" fseek %d, %d\n", SPOOL_DATA_START_OFFSET, SEEK_SET);
- (void)fseek(mbox_file, SPOOL_DATA_START_OFFSET, SEEK_SET);
+ (void) fseek (mbox_file, SPOOL_DATA_START_OFFSET, SEEK_SET);
- start = time(NULL);
+ start = time (NULL);
/* socket does not start with '/' -> network socket */
- if (arg_socket_addr[0] != '/') {
- if (sscanf(CS arg_socket_addr, "%s %u", tcp_addr, &tcp_port) != 2 ) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: Invalid rspamd address: '%s'", arg_socket_addr);
- *yield = string_sprintf("rspamd dlfunc: Invalid rspamd address: '%s'", arg_socket_addr);
- goto RETURN_DEFER;
- }
+ if (arg_socket_addr[0] != '/') {
+ if (sscanf (CS arg_socket_addr, "%s %u", tcp_addr, &tcp_port) != 2 ) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: Invalid rspamd address: '%s'",
+ arg_socket_addr);
+ *yield = string_sprintf (
+ "rspamd dlfunc: Invalid rspamd address: '%s'",
+ arg_socket_addr);
+ goto RETURN_DEFER;
+ }
- /* Lookup the host */
- if((he = gethostbyname(CS tcp_addr)) == 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: failed to lookup host '%s'", tcp_addr);
- *yield = string_sprintf("rspamd dlfunc: failed to lookup host '%s'", tcp_addr);
- goto RETURN_DEFER;
- }
+ /* Lookup the host */
+ if ((he = gethostbyname (CS tcp_addr)) == 0) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: failed to lookup host '%s'", tcp_addr);
+ *yield = string_sprintf (
+ "rspamd dlfunc: failed to lookup host '%s'", tcp_addr);
+ goto RETURN_DEFER;
+ }
- in = *(struct in_addr *) he->h_addr_list[0];
+ in = *(struct in_addr *) he->h_addr_list[0];
/* contact a rspamd */
- if ((rspamd_sock = ip_socket(SOCK_STREAM, AF_INET)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: TCP socket creation failed: %s", strerror(errno));
- *yield = string_sprintf("rspamd dlfunc: TCP socket creation failed: %s", strerror(errno));
- goto RETURN_DEFER;
- };
-
- if (ip_connect(rspamd_sock, AF_INET, (uschar*)inet_ntoa(in), tcp_port, 5, FALSE) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: connection to %s, port %u failed: %s", tcp_addr, tcp_port, strerror(errno));
- *yield = string_sprintf("rspamd dlfunc: connection to %s, port %u failed: %s", tcp_addr, tcp_port, strerror(errno));
- goto RETURN_DEFER;
- }
+ if ((rspamd_sock = ip_socket (SOCK_STREAM, AF_INET)) < 0) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: TCP socket creation failed: %s",
+ strerror (errno));
+ *yield = string_sprintf (
+ "rspamd dlfunc: TCP socket creation failed: %s",
+ strerror (errno));
+ goto RETURN_DEFER;
+ };
+
+ if (ip_connect (rspamd_sock, AF_INET, (uschar *) inet_ntoa (in),
+ tcp_port, 5, FALSE) < 0) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: connection to %s, port %u failed: %s",
+ tcp_addr, tcp_port, strerror (errno));
+ *yield = string_sprintf (
+ "rspamd dlfunc: connection to %s, port %u failed: %s",
+ tcp_addr, tcp_port, strerror (errno));
+ goto RETURN_DEFER;
+ }
//debug_printf(" Use TCP socket %s:%d\n", tcp_addr, tcp_port);
- } else {
- if ((rspamd_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: Unable to acquire socket (%s)", strerror(errno));
- *yield = string_sprintf("rspamd dlfunc: Unable to acquire socket (%s)", strerror(errno));
- goto RETURN_DEFER;
- }
-
- server.sun_family = AF_UNIX;
- Ustrcpy(server.sun_path, arg_socket_addr);
+ } else {
+ if ((rspamd_sock = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: Unable to acquire socket (%s)",
+ strerror (errno));
+ *yield = string_sprintf (
+ "rspamd dlfunc: Unable to acquire socket (%s)",
+ strerror (errno));
+ goto RETURN_DEFER;
+ }
- if (connect(rspamd_sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: Unable to connect to UNIX socket %s (%s)", socket, strerror(errno) );
- *yield = string_sprintf("rspamd dlfunc: Unable to connect to UNIX socket %s (%s)", socket, strerror(errno) );
- goto RETURN_DEFER;
- }
+ server.sun_family = AF_UNIX;
+ Ustrcpy (server.sun_path, arg_socket_addr);
+
+ if (connect (rspamd_sock, (struct sockaddr *) &server,
+ sizeof (struct sockaddr_un)) < 0) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: Unable to connect to UNIX socket %s (%s)",
+ socket, strerror (errno));
+ *yield = string_sprintf (
+ "rspamd dlfunc: Unable to connect to UNIX socket %s (%s)",
+ socket, strerror (errno));
+ goto RETURN_DEFER;
+ }
//debug_printf(" Use UNIX Domain socket %s\n", arg_socket_addr);
- }
+ }
// now we are connected to rspamd on rspamd_sock
- memset(spamd_buffer2, 0, sizeof(spamd_buffer2));
- offset = 0;
+ memset (spamd_buffer2, 0, sizeof (spamd_buffer2));
+ offset = 0;
- // headers list
- tmp_headerlist = NULL;
- header_last = NULL;
- for (my_header = header_list; my_header; my_header = my_header->next) {
+ // headers list
+ tmp_headerlist = NULL;
+ header_last = NULL;
+ for (my_header = header_list; my_header; my_header = my_header->next) {
if ((my_header->type != '*') && (my_header->type != htype_old)) {
- header_new = store_get(sizeof(header_line));
+ header_new = store_get (sizeof (header_line));
header_new->text = my_header->text;
header_new->slen = my_header->slen;
header_new->type = my_header->type;
header_new->next = NULL;
- //debug_printf(" copy header item: '%s'\n", my_header->text);
-
- max_len = sizeof(spamd_buffer2) - offset - 1;
+ //debug_printf(" copy header item: '%s'\n", my_header->text);
+
+ max_len = sizeof (spamd_buffer2) - offset - 1;
len = my_header->slen;
if (len > max_len) len = max_len;
- Ustrncpy(spamd_buffer2 + offset, my_header->text, len);
- offset += len;
-
+ Ustrncpy (spamd_buffer2 + offset, my_header->text, len);
+ offset += len;
+
if (header_last != NULL) header_last->next = header_new;
header_last = header_new;
}
- }
+ }
- s = string_sprintf("\n");
- max_len = sizeof(spamd_buffer2) - offset - 1;
- len = Ustrlen(s);
- if (len > max_len) len = max_len;
- Ustrncpy(spamd_buffer2 + offset, s, len);
- offset += len;
+ s = string_sprintf ("\n");
+ max_len = sizeof (spamd_buffer2) - offset - 1;
+ len = Ustrlen (s);
+ if (len > max_len) len = max_len;
+ Ustrncpy (spamd_buffer2 + offset, s, len);
+ offset += len;
//debug_printf(" Headers size: %d\n", offset);
- mbox_size += offset;
+ mbox_size += offset;
//debug_printf(" Total message size: %d\n", mbox_size);
// copy request to buffer
- memset(spamd_buffer, 0, sizeof(spamd_buffer));
- string_format(spamd_buffer,
- sizeof(spamd_buffer),
- "POST /checkv2 HTTP/1.0\r\nContent-length: " OFF_T_FMT "\r\nPass: all\r\nQueue-Id: %s\r\nFrom: %s\r\nRecipient-Number: %d\r\n",
- mbox_size, message_id, sender_address, recipients_count);
- for (i = 0; i < recipients_count; i ++)
- string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "Rcpt: %s\r\n", recipients_list[i].address);
- if ((helo = expand_string(US"$sender_helo_name")) != NULL && *helo != '\0')
- string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "Helo: %s\r\n", helo);
-
- if ((sender_host_name = expand_string(US"$sender_host_name")) != NULL && *sender_host_name != '\0')
- string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "Hostname: %s\r\n", sender_host_name);
- //else
- //string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "Hostname: unknown\r\n");
-
- if (sender_host_address != NULL)
-
- string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "IP: %s\r\n", sender_host_address);
- string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "Pass: all\r\n");
+ memset (spamd_buffer, 0, sizeof (spamd_buffer));
+ string_format (spamd_buffer,
+ sizeof (spamd_buffer),
+ "POST /checkv2 HTTP/1.0\r\nContent-length: "
+ OFF_T_FMT
+ "\r\nPass: all\r\nQueue-Id: %s\r\nFrom: %s\r\nRecipient-Number: %d\r\n",
+ mbox_size, message_id, sender_address, recipients_count);
+ for (i = 0; i < recipients_count; i++) {
+ string_format (spamd_buffer + Ustrlen (spamd_buffer),
+ sizeof (spamd_buffer) - Ustrlen (spamd_buffer), "Rcpt: %s\r\n",
+ recipients_list[i].address);
+ }
+ if ((helo = expand_string (US"$sender_helo_name")) != NULL && *helo != '\0')
+ string_format (spamd_buffer + Ustrlen (spamd_buffer),
+ sizeof (spamd_buffer) - Ustrlen (spamd_buffer), "Helo: %s\r\n",
+ helo);
+
+ if ((sender_host_name = expand_string (US"$sender_host_name")) != NULL &&
+ *sender_host_name != '\0')
+ string_format (spamd_buffer + Ustrlen (spamd_buffer),
+ sizeof (spamd_buffer) - Ustrlen (spamd_buffer), "Hostname: %s\r\n",
+ sender_host_name);
+ //else
+ //string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "Hostname: unknown\r\n");
+
+ if (sender_host_address != NULL)
+
+ string_format (spamd_buffer + Ustrlen (spamd_buffer),
+ sizeof (spamd_buffer) - Ustrlen (spamd_buffer), "IP: %s\r\n",
+ sender_host_address);
+ string_format (spamd_buffer + Ustrlen (spamd_buffer),
+ sizeof (spamd_buffer) - Ustrlen (spamd_buffer), "Pass: all\r\n");
//authenticated_id
- if ((authenticated_id = expand_string(US"$authenticated_id")) != NULL && *authenticated_id != '\0')
- string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "User: %s\r\n", authenticated_id);
+ if ((authenticated_id = expand_string (US"$authenticated_id")) != NULL &&
+ *authenticated_id != '\0')
+ string_format (spamd_buffer + Ustrlen (spamd_buffer),
+ sizeof (spamd_buffer) - Ustrlen (spamd_buffer), "User: %s\r\n",
+ authenticated_id);
- string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "\r\n");
+ string_format (spamd_buffer + Ustrlen (spamd_buffer),
+ sizeof (spamd_buffer) - Ustrlen (spamd_buffer), "\r\n");
//debug_printf(" Send to socket: %s", spamd_buffer);
// send our request
- if (send(rspamd_sock, spamd_buffer, Ustrlen(spamd_buffer), 0) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: rspamd send failed: %s", strerror(errno));
- goto RETURN_DEFER;
- }
+ if (send (rspamd_sock, spamd_buffer, Ustrlen (spamd_buffer), 0) < 0) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: rspamd send failed: %s", strerror (errno));
+ goto RETURN_DEFER;
+ }
- /*
- * now send the data buffer and spool file
- */
+ /*
+ * now send the data buffer and spool file
+ */
- Ustrcpy(big_buffer, "sending data block");
+ Ustrcpy (big_buffer, "sending data block");
//debug_printf("sending data block\n");
//debug_printf(" Send to socket: %s", spamd_buffer2);
- wrote = send(rspamd_sock, spamd_buffer2, strlen(spamd_buffer2), 0);
- if (wrote == -1) goto WRITE_FAILED;
+ wrote = send (rspamd_sock, spamd_buffer2, strlen (spamd_buffer2), 0);
+ if (wrote == -1) goto WRITE_FAILED;
//debug_printf(" wrote to socket %d bytes\n", wrote);
- /*
- * Note: poll() is not supported in OSX 10.2.
- */
+ /*
+ * Note: poll() is not supported in OSX 10.2.
+ */
#ifndef NO_POLL_H
- pollfd.fd = rspamd_sock;
- pollfd.events = POLLOUT;
+ pollfd.fd = rspamd_sock;
+ pollfd.events = POLLOUT;
#endif
// (void)fcntl(rspamd_sock, F_SETFL, O_NONBLOCK);
- do {
- read = fread(spamd_buffer,1,sizeof(spamd_buffer),mbox_file);
-if (read < sizeof(spamd_buffer)) spamd_buffer[read] = 0;
+ do {
+ read = fread (spamd_buffer, 1, sizeof (spamd_buffer), mbox_file);
+ if (read < sizeof (spamd_buffer)) spamd_buffer[read] = 0;
//debug_printf(" Read from spool file: %s", spamd_buffer);
- if (read > 0) {
- offset = 0;
-again:
+ if (read > 0) {
+ offset = 0;
+ again:
#ifndef NO_POLL_H
- result = poll(&pollfd, 1, 1000);
- if (result == -1 && errno == EINTR)
- continue;
- else if (result < 1) {
- if (result == -1)
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: %s on rspamd socket", strerror(errno));
- else {
- if (time(NULL) - start < RSPAMD_TIMEOUT)
- goto again;
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: timed out writing rspamd socket");
- *yield = string_sprintf("rspamd dlfunc: timed out writing rspamd socket");
- }
- goto RETURN_DEFER;
- }
+ result = poll (&pollfd, 1, 1000);
+ if (result == -1 && errno == EINTR)
+ continue;
+ else if (result < 1) {
+ if (result == -1)
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: %s on rspamd socket",
+ strerror (errno));
+ else {
+ if (time (NULL) - start < RSPAMD_TIMEOUT)
+ goto again;
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: timed out writing rspamd socket");
+ *yield = string_sprintf (
+ "rspamd dlfunc: timed out writing rspamd socket");
+ }
+ goto RETURN_DEFER;
+ }
#endif
- wrote = send(rspamd_sock, spamd_buffer + offset, read - offset, 0);
+ wrote = send (rspamd_sock, spamd_buffer + offset, read - offset, 0);
//debug_printf(" Send to socket %d bytes: %s", read - offset, spamd_buffer + offset);
//debug_printf(" wrote to socket %d bytes\n", wrote);
- if (wrote == -1) goto WRITE_FAILED;
- if (offset + wrote != read) {
- offset += wrote;
- goto again;
- }
+ if (wrote == -1) goto WRITE_FAILED;
+ if (offset + wrote != read) {
+ offset += wrote;
+ goto again;
+ }
+ }
+ } while (!feof (mbox_file) && !ferror (mbox_file));
+
+ if (ferror (mbox_file)) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: error reading spool file: %s",
+ strerror (errno));
+ *yield = string_sprintf ("rspamd dlfunc: error reading spool file: %s",
+ strerror (errno));
+ goto RETURN_DEFER;
}
- } while (!feof(mbox_file) && !ferror(mbox_file));
-
- if (ferror(mbox_file)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: error reading spool file: %s", strerror(errno));
- *yield = string_sprintf("rspamd dlfunc: error reading spool file: %s", strerror(errno));
- goto RETURN_DEFER;
- }
- /*
- read rspamd response using what's left of the timeout.
- */
+ /*
+ read rspamd response using what's left of the timeout.
+ */
//debug_printf("read rspamd response using what's left of the timeout (%d sec)\n", RSPAMD_TIMEOUT - time(NULL) + start);
- memset(spamd_buffer, 0, sizeof(spamd_buffer));
- offset = 0;
- while ((i = ip_recv(rspamd_sock,
- spamd_buffer + offset,
- sizeof(spamd_buffer) - offset - 1,
- RSPAMD_TIMEOUT - time(NULL) + start)) > 0
- ) {
+ memset (spamd_buffer, 0, sizeof (spamd_buffer));
+ offset = 0;
+ while ((i = ip_recv (rspamd_sock,
+ spamd_buffer + offset,
+ sizeof (spamd_buffer) - offset - 1,
+ RSPAMD_TIMEOUT - time (NULL) + start)) > 0
+ ) {
//debug_printf(" read %d bytes from socket\n", i);
offset += i;
- }
+ }
//debug_printf(" total read %d bytes from socket\n", offset);
/* error handling */
- if((i <= 0) && (errno != 0)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: error reading from rspamd socket: %s", strerror(errno));
- *yield = string_sprintf("rspamd dlfunc: error reading from rspamd socket: %s", strerror(errno));
- goto RETURN_DEFER;
- }
+ if ((i <= 0) && (errno != 0)) {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: error reading from rspamd socket: %s",
+ strerror (errno));
+ *yield = string_sprintf (
+ "rspamd dlfunc: error reading from rspamd socket: %s",
+ strerror (errno));
+ goto RETURN_DEFER;
+ }
//debug_printf("read from socket: %s\n", spamd_buffer);
- if (rspamd_sock > 0) {
- (void)close(rspamd_sock);
- rspamd_sock = 0;
- }
- if (mbox_file != NULL) {
- (void)fclose(mbox_file);
+ if (rspamd_sock > 0) {
+ (void) close (rspamd_sock);
+ rspamd_sock = 0;
+ }
+ if (mbox_file != NULL) {
+ (void) fclose (mbox_file);
mbox_file = NULL;
- }
+ }
- //Parse http response code
- if (strstr(spamd_buffer, "HTTP/1.1 200 OK") == NULL && strstr(spamd_buffer, "HTTP/1.0 200 OK") == NULL) {
- *yield = string_sprintf("rspamd dlfunc: HTTP return code != 200: %s", spamd_buffer);
+ //Parse http response code
+ if (strstr (spamd_buffer, "HTTP/1.1 200 OK") == NULL &&
+ strstr (spamd_buffer, "HTTP/1.0 200 OK") == NULL) {
+ *yield = string_sprintf ("rspamd dlfunc: HTTP return code != 200: %s",
+ spamd_buffer);
goto RETURN_DEFER;
}
-
+
//Parse http response
- int pos = strpos(spamd_buffer, "\r\n\r\n", 0);
- if (pos == -1) {
- *yield = string_sprintf("rspamd dlfunc: HTTP response error: %s", spamd_buffer);
+ int pos = strpos (spamd_buffer, "\r\n\r\n", 0);
+ if (pos == -1) {
+ *yield = string_sprintf ("rspamd dlfunc: HTTP response error: %s",
+ spamd_buffer);
goto RETURN_DEFER;
}
- char *json_answer = string_sprintf("%s", spamd_buffer +pos+4);
-
+ char *json_answer = string_sprintf ("%s", spamd_buffer + pos + 4);
+
//Parse json
- cJSON *json = NULL;
- json = cJSON_Parse(json_answer);
-
- if (!json) {
- *yield = string_sprintf("rspamd dlfunc: Json parse error, json: %s", spamd_buffer);
+ cJSON *json = NULL;
+ json = cJSON_Parse (json_answer);
+
+ if (!json) {
+ *yield = string_sprintf ("rspamd dlfunc: Json parse error, json: %s",
+ spamd_buffer);
goto RETURN_DEFER;
}
-
+
//Score
- cJSON *score = cJSON_GetObjectItem(json, "score");
- if(!cJSON_IsNumber(score)) {
- *yield = string_sprintf("rspamd dlfunc: Json parse error, no found 'score'");
+ cJSON *score = cJSON_GetObjectItem (json, "score");
+ if (!cJSON_IsNumber (score)) {
+ *yield = string_sprintf (
+ "rspamd dlfunc: Json parse error, no found 'score'");
goto RETURN_DEFER;
}
//required_score
- cJSON *required_score = cJSON_GetObjectItem(json, "required_score");
- if(!cJSON_IsNumber(required_score)) {
- *yield = string_sprintf("rspamd dlfunc: Json parse error, no found 'required_score'");
+ cJSON *required_score = cJSON_GetObjectItem (json, "required_score");
+ if (!cJSON_IsNumber (required_score)) {
+ *yield = string_sprintf (
+ "rspamd dlfunc: Json parse error, no found 'required_score'");
goto RETURN_DEFER;
}
//Action
- cJSON *action = cJSON_GetObjectItem(json, "action");
- if(!cJSON_IsString(action)) {
- *yield = string_sprintf("rspamd dlfunc: Json parse error, no found 'action'");
+ cJSON *action = cJSON_GetObjectItem (json, "action");
+ if (!cJSON_IsString (action)) {
+ *yield = string_sprintf (
+ "rspamd dlfunc: Json parse error, no found 'action'");
goto RETURN_DEFER;
}
- *yield = string_sprintf("[%.2f / %.2f]", score->valuedouble, required_score->valuedouble);
-
+ *yield = string_sprintf ("[%.2f / %.2f]", score->valuedouble,
+ required_score->valuedouble);
+
//Parse scan time
- cJSON *time_real = cJSON_GetObjectItem(json, "time_real");
- cJSON *time_virtual = cJSON_GetObjectItem(json, "time_virtual");
- if(cJSON_IsNumber(time_real) && cJSON_IsNumber(time_virtual)) *yield = string_sprintf("%s [time: %.6f, %.6f]", *yield, time_real->valuedouble, time_virtual->valuedouble);
-
- *yield = string_sprintf("%s\n Action: %s\n", *yield, action->valuestring);
-
+ cJSON *time_real = cJSON_GetObjectItem (json, "time_real");
+ cJSON *time_virtual = cJSON_GetObjectItem (json, "time_virtual");
+ if (cJSON_IsNumber (time_real) && cJSON_IsNumber (time_virtual))
+ *yield = string_sprintf ("%s [time: %.6f, %.6f]", *yield,
+ time_real->valuedouble, time_virtual->valuedouble);
+
+ *yield = string_sprintf ("%s\n Action: %s\n", *yield, action->valuestring);
+
cJSON *symbol = NULL;
cJSON *symbol_name = NULL;
cJSON *symbol_score = NULL;
cJSON *symbol_options = NULL;
cJSON *option = NULL;
-
+
//parse symbols
- cJSON *symbols = cJSON_GetObjectItem(json, "symbols");
- for(i=0; i<cJSON_GetArraySize(symbols); i++) {
- symbol = cJSON_GetArrayItem(symbols, i);
- symbol_name = cJSON_GetObjectItem(symbol, "name");
- symbol_score = cJSON_GetObjectItem(symbol, "score");
- symbol_options = cJSON_GetObjectItem(symbol, "options");
-
- if(cJSON_IsString(symbol_name)) *yield = string_sprintf("%s %s", *yield, symbol_name->valuestring);
- if(cJSON_IsNumber(symbol_score)) *yield = string_sprintf("%s(%.2f)", *yield, symbol_score->valuedouble);
-
+ cJSON *symbols = cJSON_GetObjectItem (json, "symbols");
+ for (i = 0; i < cJSON_GetArraySize (symbols); i++) {
+ symbol = cJSON_GetArrayItem (symbols, i);
+ symbol_name = cJSON_GetObjectItem (symbol, "name");
+ symbol_score = cJSON_GetObjectItem (symbol, "score");
+ symbol_options = cJSON_GetObjectItem (symbol, "options");
+
+ if (cJSON_IsString (symbol_name))
+ *yield = string_sprintf ("%s %s", *yield, symbol_name->valuestring);
+ if (cJSON_IsNumber (symbol_score))
+ *yield = string_sprintf ("%s(%.2f)", *yield,
+ symbol_score->valuedouble);
+
//parse options
- c = cJSON_GetArraySize(symbol_options);
- if(c > 0) *yield = string_sprintf("%s[", *yield);
- for(j=0; j<c; j++) {
- option = cJSON_GetArrayItem(symbol_options, j);
- if(cJSON_IsString(option)) {
- *yield = string_sprintf("%s%s", *yield, option->valuestring);
- if(j < c-1) *yield = string_sprintf("%s, ", *yield);
+ c = cJSON_GetArraySize (symbol_options);
+ if (c > 0) *yield = string_sprintf ("%s[", *yield);
+ for (j = 0; j < c; j++) {
+ option = cJSON_GetArrayItem (symbol_options, j);
+ if (cJSON_IsString (option)) {
+ *yield = string_sprintf ("%s%s", *yield, option->valuestring);
+ if (j < c - 1) *yield = string_sprintf ("%s, ", *yield);
}
}
- if(c > 0) *yield = string_sprintf("%s]", *yield);
-
- *yield = string_sprintf("%s\n", *yield);
+ if (c > 0) *yield = string_sprintf ("%s]", *yield);
+
+ *yield = string_sprintf ("%s\n", *yield);
}
-
+
//Parse messages
cJSON *mess = NULL;
- cJSON *messages = cJSON_GetObjectItem(json, "messages");
- c = cJSON_GetArraySize(messages);
- for(i=0; i<c; i++) {
- mess = cJSON_GetArrayItem(messages, i);
- if(cJSON_IsString(mess)) *yield = string_sprintf("%s %s", *yield, mess->valuestring);
- if(i < c-1) *yield = string_sprintf("%s\n", *yield);
+ cJSON *messages = cJSON_GetObjectItem (json, "messages");
+ c = cJSON_GetArraySize (messages);
+ for (i = 0; i < c; i++) {
+ mess = cJSON_GetArrayItem (messages, i);
+ if (cJSON_IsString (mess))
+ *yield = string_sprintf ("%s %s", *yield, mess->valuestring);
+ if (i < c - 1) *yield = string_sprintf ("%s\n", *yield);
}
-
- return OK;
+
+ return OK;
/* Come here if any call to read_response, other than a response after the data
phase, failed. Analyse the error, and if isn't too bad, send a QUIT
command. Wait for the response with a short timeout, so we don't wind up this
process before the far end has had time to read the QUIT. */
-WRITE_FAILED:
-{
- log_write(0, LOG_MAIN|LOG_PANIC,
- "rspamd dlfunc: %s on rspamd socket", strerror(errno));
- *yield = string_sprintf("rspamd dlfunc: %s on rspamd socket", strerror(errno));
- goto RETURN_DEFER;
-}
+ WRITE_FAILED:
+ {
+ log_write (0, LOG_MAIN | LOG_PANIC,
+ "rspamd dlfunc: %s on rspamd socket", strerror (errno));
+ *yield = string_sprintf ("rspamd dlfunc: %s on rspamd socket",
+ strerror (errno));
+ goto RETURN_DEFER;
+ }
-RESPONSE_FAILED:
-{
- int code;
- int save_errno;
- int more_errno;
- uschar message_buffer[256];
- uschar *message;
+ RESPONSE_FAILED:
+ {
+ int code;
+ int save_errno;
+ int more_errno;
+ uschar message_buffer[256];
+ uschar *message;
- save_errno = errno;
+ save_errno = errno;
- message = &message_buffer[0];
+ message = &message_buffer[0];
- log_write(0, LOG_MAIN|LOG_PANIC, "rspamd dlfunc: %s", message);
- *yield = string_sprintf("rspamd dlfunc: %s", message);
+ log_write (0, LOG_MAIN | LOG_PANIC, "rspamd dlfunc: %s", message);
+ *yield = string_sprintf ("rspamd dlfunc: %s", message);
- goto RETURN_DEFER;
-}
+ goto RETURN_DEFER;
+ }
-RETURN_DEFER:
-{
- if (rspamd_sock > 0) {
- (void)close(rspamd_sock);
- rspamd_sock = 0;
- }
- if (mbox_file != NULL) {
- (void)fclose(mbox_file);
- mbox_file = NULL;
- }
-
- return(defer_ok ? OK : ERROR);
-}
+ RETURN_DEFER:
+ {
+ if (rspamd_sock > 0) {
+ (void) close (rspamd_sock);
+ rspamd_sock = 0;
+ }
+ if (mbox_file != NULL) {
+ (void) fclose (mbox_file);
+ mbox_file = NULL;
+ }
+
+ return (defer_ok ? OK : ERROR);
+ }
- return OK;
+ return OK;
}