Browse Source

Optimize exim dlfunc

pull/1913/head
AL 8 years ago
committed by GitHub
parent
commit
a2cba47734
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 218
      contrib/exim/dlfunc-json/rspamd.c

218
contrib/exim/dlfunc-json/rspamd.c

@ -25,11 +25,17 @@ and source code of Victor Ustugov http://mta.org.ua/
#include <sys/wait.h>
#include <stdarg.h>
#include <errno.h>
#include <cJSON.h>
#include "cJSON.h"
#include "cJSON.c"
#define RSPAMD_TIMEOUT 120
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)
{
@ -49,6 +55,7 @@ int rspamd(uschar **yield, int argc, uschar *argv[]) {
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;
@ -89,7 +96,7 @@ int rspamd(uschar **yield, int argc, uschar *argv[]) {
} else {
defer_ok = 0;
}
debug_printf(" defer_ok: %d\n", defer_ok);
//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,
@ -105,7 +112,7 @@ debug_printf(" defer_ok: %d\n", defer_ok);
} else {
sprintf(mbox_path, "%s/input/%s/%s-D", spool_directory, message_subdir, message_id);
}
debug_printf(" Open spool file: %s\n", mbox_path);
//debug_printf(" Open spool file: %s\n", mbox_path);
mbox_file = fopen(mbox_path,"rb");
if (!mbox_file) {
@ -115,10 +122,10 @@ debug_printf(" Open spool file: %s\n", mbox_path);
(void)fseek(mbox_file, 0, SEEK_END);
mbox_size = ftell(mbox_file);
debug_printf(" Total spool file size: %d\n", mbox_size);
//debug_printf(" Total spool file size: %d\n", mbox_size);
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);
//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);
start = time(NULL);
@ -157,7 +164,7 @@ debug_printf(" fseek %d, %d\n", SPOOL_DATA_START_OFFSET, SEEK_SET);
goto RETURN_DEFER;
}
debug_printf(" Use TCP socket %s:%d\n", tcp_addr, tcp_port);
//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,
@ -176,7 +183,7 @@ debug_printf(" Use TCP socket %s:%d\n", tcp_addr, tcp_port);
goto RETURN_DEFER;
}
debug_printf(" Use UNIX Domain socket %s\n", arg_socket_addr);
//debug_printf(" Use UNIX Domain socket %s\n", arg_socket_addr);
}
// now we are connected to rspamd on rspamd_sock
@ -184,163 +191,30 @@ debug_printf(" Use UNIX Domain socket %s\n", arg_socket_addr);
memset(spamd_buffer2, 0, sizeof(spamd_buffer2));
offset = 0;
address = expand_string(US"${sender_address}");
if (address && *address) {
s = string_sprintf("Return-path: <%s>\n", address);
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;
}
// address = expand_string(US"${if def:received_for{$received_for}}");
address = expand_string(US"${received_for}");
if (!address || !*address) address = expand_string(US"${recipients}");
if (!address || !*address) address = expand_string(US"${local_part}@${domain}");
if (address && *address) {
s = string_sprintf("Envelope-To: %s\n", address);
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("Delivery-date: %s\n", tod_stamp(tod_full));
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;
// create links to original headers list
// 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->text = string_copyn(my_header->text, my_header->slen);
// header_new->text = store_get(my_header->slen);
// memcpy(header_new->text, my_header->text, my_header->slen);
header_new->text = my_header->text;
header_new->slen = my_header->slen;
header_new->type = my_header->type;
header_new->next = NULL;
//debug_printf(" create a copy of header item: '%s'\n", header_new->text);
if (tmp_headerlist == NULL) tmp_headerlist = header_new;
if (header_last != NULL) header_last->next = header_new;
header_last = header_new;
}
}
#ifdef WITH_EXPERIMENTAL_REMOVE_HEADER
// headers removed by acl_check_data
if (acl_removed_headers != NULL) {
for (my_header = tmp_headerlist; my_header != NULL; my_header = my_header->next) {
uschar *list;
list = acl_removed_headers;
int sep = ':'; // This is specified as a colon-separated list
uschar buffer[128];
while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL) {
int len = Ustrlen(s);
if (header_testname(my_header, s, len, FALSE)) {
//debug_printf(" header removed by acl_check_data: '%s'; '%s'\n", s, my_header->text);
my_header->type = htype_old;
if ((my_header->type != '*') && (my_header->type != htype_old)) {
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;
len = my_header->slen;
if (len > max_len) len = max_len;
Ustrncpy(spamd_buffer2 + offset, my_header->text, len);
offset += len;
if (header_last != NULL) header_last->next = header_new;
header_last = header_new;
}
}
}
}
#endif
// headers added by acl_check_data
my_header = acl_added_headers;
while (my_header != NULL) {
//debug_printf(" header added by acl_check_data: '%s'\n", my_header->text);
header_new = store_get(sizeof(header_line));
//// header_new->text = string_copyn(my_header->text, my_header->slen);
// header_new->text = store_get(my_header->slen);
// memcpy(header_new->text, my_header->text, my_header->slen);
header_new->text = my_header->text;
header_new->slen = my_header->slen;
switch(my_header->type) {
case htype_add_top:
// add header at top
header_new->next = tmp_headerlist;
tmp_headerlist = header_new;
break;
case htype_add_rec:
// add header after Received:
if (last_received == NULL) {
last_received = tmp_headerlist;
while (!header_testname(last_received, US"Received", 8, FALSE))
last_received = last_received->next;
while (last_received->next != NULL && header_testname(last_received->next, US"Received", 8, FALSE))
last_received = last_received->next;
}
header_new->next = last_received->next;
last_received->next = header_new;
break;
case htype_add_rfc:
// add header before any header which is NOT Received: or Resent-
last_received = tmp_headerlist;
while ( (last_received->next != NULL) &&
( (header_testname(last_received->next, US"Received", 8, FALSE)) ||
(header_testname_incomplete(last_received->next, US"Resent-", 7, FALSE)) ) )
last_received = last_received->next;
// last_received now points to the last Received: or Resent-* header
// in an uninterrupted chain of those header types (seen from the beginning
// of all headers. Our current header must follow it.
header_new->next = last_received->next;
last_received->next = header_new;
break;
default:
// htype_add_bot
// add header at bottom
header_new->next = NULL;
header_last->next = header_new;
break;
}
if (header_new->next == NULL) header_last = header_new;
my_header = my_header->next;
}
// copy all the headers to data buffer
my_header = tmp_headerlist;
while (my_header) {
if ((my_header->type != '*') && (my_header->type != htype_old)) {
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;
//debug_printf(" copy header item: '%s'\n", my_header->text);
}
//// if (my_header->text) store_release(my_header->text);
header_last = my_header;
my_header = my_header->next;
// if (header_last) store_release(header_last);
}
// s = string_sprintf("\r\n");
s = string_sprintf("\n");
max_len = sizeof(spamd_buffer2) - offset - 1;
len = Ustrlen(s);
@ -348,9 +222,9 @@ debug_printf(" Use UNIX Domain socket %s\n", arg_socket_addr);
Ustrncpy(spamd_buffer2 + offset, s, len);
offset += len;
debug_printf(" Headers size: %d\n", offset);
//debug_printf(" Headers size: %d\n", offset);
mbox_size += offset;
debug_printf(" Total message size: %d\n", mbox_size);
//debug_printf(" Total message size: %d\n", mbox_size);
// copy request to buffer
memset(spamd_buffer, 0, sizeof(spamd_buffer));
@ -379,7 +253,7 @@ debug_printf(" Total message size: %d\n", mbox_size);
string_format(spamd_buffer+Ustrlen(spamd_buffer), sizeof(spamd_buffer)-Ustrlen(spamd_buffer), "\r\n");
debug_printf(" Send to socket: %s", spamd_buffer);
//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,
@ -392,12 +266,12 @@ debug_printf(" Send to socket: %s", spamd_buffer);
*/
Ustrcpy(big_buffer, "sending data block");
debug_printf("sending data block\n");
//debug_printf("sending data block\n");
debug_printf(" Send to socket: %s", spamd_buffer2);
//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);
//debug_printf(" wrote to socket %d bytes\n", wrote);
/*
* Note: poll() is not supported in OSX 10.2.
@ -411,7 +285,7 @@ debug_printf(" wrote to socket %d bytes\n", wrote);
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);
//debug_printf(" Read from spool file: %s", spamd_buffer);
if (read > 0) {
offset = 0;
again:
@ -435,8 +309,8 @@ again:
}
#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);
//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;
@ -456,7 +330,7 @@ debug_printf(" wrote to socket %d bytes\n", wrote);
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);
//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;
@ -465,10 +339,10 @@ debug_printf("read rspamd response using what's left of the timeout (%d sec)\n",
sizeof(spamd_buffer) - offset - 1,
RSPAMD_TIMEOUT - time(NULL) + start)) > 0
) {
debug_printf(" read %d bytes from socket\n", i);
//debug_printf(" read %d bytes from socket\n", i);
offset += i;
}
debug_printf(" total read %d bytes from socket\n", offset);
//debug_printf(" total read %d bytes from socket\n", offset);
/* error handling */
if((i <= 0) && (errno != 0)) {
@ -478,7 +352,7 @@ debug_printf(" total read %d bytes from socket\n", offset);
goto RETURN_DEFER;
}
debug_printf("read from socket: %s\n", spamd_buffer);
//debug_printf("read from socket: %s\n", spamd_buffer);
if (rspamd_sock > 0) {
(void)close(rspamd_sock);

Loading…
Cancel
Save