/*-
* Copyright (c) 2013-2015, Alexey Savelyev <info@homeweb.ru>
+ * Copyright 2017 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
//-------------------------------------------------------------------------
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;
-}
-
-int
-rspamd (uschar **yield, int argc, uschar *argv[])
-{
+rspamd (uschar **yield, int argc, uschar *argv[]) {
char *arg_socket_addr;
char *arg_defer_ok;
int defer_ok;
uschar *helo;
uschar *sender_host_name;
uschar *authenticated_id;
- char mbox_path[512];
+ char mbox_path[8192];
int max_len, len;
int rspamd_sock = 0;
struct hostent *he;
if (argc < 2) {
defer_ok = 0;
- } else if (
- (strcmpic (arg_defer_ok, US
- "1") == 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") == 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,
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,
+ snprintf (mbox_path, sizeof (mbox_path), "%s/input/%s-D",
+ spool_directory,
message_id);
+ } else {
+ snprintf (mbox_path, sizeof (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");
if (!mbox_file) {
(void) fseek (mbox_file, SPOOL_DATA_START_OFFSET, SEEK_SET);
start = time (NULL);
-/* socket does not start with '/' -> network socket */
+ /* 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,
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);
+ "POST /checkv2 HTTP/1.0\r\nContent-length: "OFF_T_FMT
+ "\r\nQueue-Id: %s\r\nFrom: %s\r\n",
+ mbox_size, message_id, sender_address);
+
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 ((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);
+ *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)
-
+ 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);
+ *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");
-//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));
/*
* now send the data buffer and spool file
*/
-
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;
-//debug_printf(" wrote to socket %d bytes\n", wrote);
+ if (wrote == -1) {
+ goto WRITE_FAILED;
+ }
/*
* Note: poll() is not supported in OSX 10.2.
#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;
+ read = fread (spamd_buffer, 1, sizeof (spamd_buffer) - 1, 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;
#ifndef NO_POLL_H
result = poll (&pollfd, 1, 1000);
- if (result == -1 && errno == EINTR)
+ if (result == -1 && errno == EINTR) {
continue;
+ }
else if (result < 1) {
if (result == -1)
log_write (0, LOG_MAIN | LOG_PANIC,
}
#endif
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 (wrote == -1) {
+ goto WRITE_FAILED;
+ }
+
if (offset + wrote != read) {
offset += wrote;
goto again;
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,
}
//Parse http response
- int pos = strpos (spamd_buffer, "\r\n\r\n", 0);
- if (pos == -1) {
+ const char *crlf_pos = strstr (spamd_buffer, "\r\n\r\n");
+ if (crlf_pos == NULL) {
*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", crlf_pos + 4);
//Parse json
cJSON *json = NULL;
symbol_score = cJSON_GetObjectItem (symbol, "score");
symbol_options = cJSON_GetObjectItem (symbol, "options");
- if (cJSON_IsString (symbol_name))
+ if (cJSON_IsString (symbol_name)) {
*yield = string_sprintf ("%s %s", *yield, symbol_name->valuestring);
- if (cJSON_IsNumber (symbol_score))
+ }
+ 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);
+ 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);
+ if (c > 0) {
+ *yield = string_sprintf ("%s]", *yield);
+ }
*yield = string_sprintf ("%s\n", *yield);
}
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))
+ if (cJSON_IsString (mess)) {
*yield = string_sprintf ("%s %s", *yield, mess->valuestring);
- if (i < c - 1) *yield = string_sprintf ("%s\n", *yield);
+ }
+
+ if (i < c - 1) {
+ *yield = string_sprintf ("%s\n", *yield);
+ }
}
return OK;