* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-???? */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003 - 2015 */
/* License: GPL */
/* Code for calling spamassassin's spamd. Called from acl.c. */
static int
spamd_param_init(spamd_address_container *spamd)
{
-/* default spamd server weight, time and backup value */
+/* default spamd server weight, time and priority value */
+spamd->is_rspamd = FALSE;
spamd->is_failed = FALSE;
-spamd->is_backup = FALSE;
spamd->weight = SPAMD_WEIGHT;
spamd->timeout = SPAMD_TIMEOUT;
spamd->retry = 0;
+spamd->priority = 1;
return 0;
}
static int
-spamd_param(const uschar *param, spamd_address_container *spamd)
+spamd_param(const uschar * param, spamd_address_container * spamd)
{
static int timesinceday = -1;
const uschar * s;
const uschar * name;
-/* check backup parameter */
-if (Ustrcmp(param, "backup") == 0)
- {
- spamd->is_backup = TRUE;
- return 0; /* OK */
- }
-
/*XXX more clever parsing could discard embedded spaces? */
-/* check weight parameter */
-if (sscanf(param, "weight=%u", &spamd->weight))
+if (sscanf(CCS param, "pri=%u", &spamd->priority))
+ return 0; /* OK */
+
+if (sscanf(CCS param, "weight=%u", &spamd->weight))
{
if (spamd->weight == 0) /* this server disabled: skip it */
return 1;
return 0; /* OK */
}
-/* check time parameter */
if (Ustrncmp(param, "time=", 5) == 0)
{
unsigned int start_h = 0, start_m = 0, start_s = 0;
static int
-spamd_get_server(spamd_address_container **spamds, int num_servers)
+spamd_get_server(spamd_address_container ** spamds, int num_servers)
{
unsigned int i;
-long rnd, weights = 0;
-static BOOL srandomed = 0;
-BOOL usebackup = FALSE;
-
-for (;;)
- {
- /* seedup, if we have only 1 server */
- if (num_servers == 1)
- return (spamds[0]->is_failed ? -1 : 0);
+spamd_address_container * sd;
+long rnd, weights;
+unsigned pri;
+static BOOL srandomed = FALSE;
- /* init ranmod */
- if (!srandomed)
- {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- srandom((unsigned int)(tv.tv_usec/1000));
- srandomed = TRUE;
- }
+/* seedup, if we have only 1 server */
+if (num_servers == 1)
+ return (spamds[0]->is_failed ? -1 : 0);
- /* get sum of all weights */
- for (i = 0; i < num_servers; i++)
- if (!spamds[i]->is_failed && spamds[i]->is_backup == usebackup)
- weights += spamds[i]->weight;
+/* init ranmod */
+if (!srandomed)
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ srandom((unsigned int)(tv.tv_usec/1000));
+ srandomed = TRUE;
+ }
- if (weights != 0)
- break;
- if (usebackup) /* all servers failed (backups too) */
- return -1;
- usebackup = TRUE;
+/* scan for highest pri */
+for (pri = 0, i = 0; i < num_servers; i++)
+ {
+ sd = spamds[i];
+ if (!sd->is_failed && sd->priority > pri) pri = sd->priority;
}
-rnd = random() % weights;
+/* get sum of weights */
+for (weights = 0, i = 0; i < num_servers; i++)
+ {
+ sd = spamds[i];
+ if (!sd->is_failed && sd->priority == pri) weights += sd->weight;
+ }
+if (weights == 0) /* all servers failed */
+ return -1;
-for (i = 0; i < num_servers; i++)
- if (!spamds[i]->is_failed && spamds[i]->is_backup == usebackup)
- if ((rnd -= spamds[i]->weight) < 0)
+for (rnd = random() % weights, i = 0; i < num_servers; i++)
+ {
+ sd = spamds[i];
+ if (!sd->is_failed && sd->priority == pri)
+ if ((rnd -= sd->weight) <= 0)
return i;
+ }
log_write(0, LOG_MAIN|LOG_PANIC,
"%s unknown error (memory/cpu corruption?)", loglabel);
int override = 0;
time_t start;
size_t read, wrote;
-struct sockaddr_un server;
#ifndef NO_POLL_H
struct pollfd pollfd;
#else /* Patch posted by Erik ? for OS X */
else
spamd_address_work = spamd_address;
-HDEBUG(D_acl) debug_printf("spamd: addrlist '%s'\n", spamd_address_work);
+DEBUG(D_acl) debug_printf("spamd: addrlist '%s'\n", spamd_address_work);
/* check if previous spamd_address was expanded and has changed. dump cached results if so */
if ( spam_ok
{
int num_servers = 0;
int current_server;
- uschar *address;
- const uschar *spamd_address_list_ptr = spamd_address_work;
+ uschar * address;
+ const uschar * spamd_address_list_ptr = spamd_address_work;
spamd_address_container * spamd_address_vector[32];
/* Check how many spamd servers we have
and register their addresses */
+ sep = 0; /* default colon-sep */
while ((address = string_nextinlist(&spamd_address_list_ptr, &sep,
NULL, 0)) != NULL)
{
unsigned args;
uschar * s;
- HDEBUG(D_acl) debug_printf("spamd: addr entry '%s'\n", address);
+ DEBUG(D_acl) debug_printf("spamd: addr entry '%s'\n", address);
sd = (spamd_address_container *)store_get(sizeof(spamd_address_container));
for (sublist = address, args = 0, spamd_param_init(sd);
args++
)
{
- HDEBUG(D_acl) debug_printf("spamd: addr parm '%s'\n", s);
+ DEBUG(D_acl) debug_printf("spamd: addr parm '%s'\n", s);
switch (args)
{
case 0: sd->hostspec = s;
{
uschar * errstr;
- debug_printf("trying server %s\n", sd->hostspec);
+ DEBUG(D_acl) debug_printf("spamd: trying server %s\n", sd->hostspec);
for (;;)
{
|| sd->retry <= 0
)
break;
- debug_printf("server %s: retry conn\n", sd->hostspec);
+ DEBUG(D_acl) debug_printf("sspamd: erver %s: retry conn\n", sd->hostspec);
while (sd->retry > 0) sd->retry = sleep(sd->retry);
}
if (spamd_sock >= 0)
const uschar * authid;
req_str = string_sprintf("CHECK RSPAMC/1.3\r\nContent-length: %lu\r\n"
- "Queue-Id: %s\r\nFrom: <%s>\r\nRecipient-Number: %d\r\n", mbox_size,
- message_id, sender_address, recipients_count);
+ "Queue-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 ++)
req_str = string_sprintf("%sRcpt: <%s>\r\n", req_str, recipients_list[i].address);
if ((helo = expand_string(US"$sender_helo_name")) != NULL && *helo != '\0')