-/* $Cambridge: exim/src/src/spam.c,v 1.18 2010/06/05 11:13:30 pdp Exp $ */
-
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
int spam_rc = 0;
uschar *prev_spamd_address_work = NULL;
-int spam(uschar **listptr) {
+int
+spam(uschar **listptr)
+{
int sep = 0;
uschar *list = *listptr;
uschar *user_name;
uschar user_name_buffer[128];
unsigned long mbox_size;
FILE *mbox_file;
- int spamd_sock;
+ int spamd_sock = -1;
uschar spamd_buffer[32600];
int i, j, offset, result;
uschar spamd_version[8];
/* socket does not start with '/' -> network socket */
if (*spamd_address_work != '/') {
- time_t now = time(NULL);
int num_servers = 0;
- int current_server = 0;
- int start_server = 0;
+ int current_server;
uschar *address = NULL;
uschar *spamd_address_list_ptr = spamd_address_work;
uschar address_buffer[256];
address_buffer,
sizeof(address_buffer))) != NULL) {
+ /* Potential memory leak as we never free the store. */
spamd_address_container *this_spamd =
(spamd_address_container *)store_get(sizeof(spamd_address_container));
return DEFER;
};
- current_server = start_server = (int)now % num_servers;
+ while ( num_servers > 0 ) {
+ int i;
- while (1) {
+ /* Randomly pick a server to try */
+ current_server = random_number( num_servers );
debug_printf("trying server %s, port %u\n",
spamd_address_vector[current_server]->tcp_addr,
spamd_address_vector[current_server]->tcp_addr,
spamd_address_vector[current_server]->tcp_port,
strerror(errno));
- current_server++;
- if (current_server >= num_servers)
- current_server = 0;
- if (current_server == start_server) {
- log_write(0, LOG_MAIN|LOG_PANIC, "spam acl condition: all spamd servers failed");
- (void)fclose(mbox_file);
- (void)close(spamd_sock);
- return DEFER;
- };
- };
+
+ (void)close(spamd_sock);
+
+ /* Remove the server from the list. XXX We should free the memory */
+ num_servers--;
+ for( i = current_server; i < num_servers; i++ )
+ spamd_address_vector[i] = spamd_address_vector[i+1];
+ }
+
+ if ( num_servers == 0 ) {
+ log_write(0, LOG_MAIN|LOG_PANIC, "spam acl condition: all spamd servers failed");
+ (void)fclose(mbox_file);
+ return DEFER;
+ }
}
else {
}
+ if (spamd_sock == -1) {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "programming fault, spamd_sock unexpectedly unset");
+ (void)fclose(mbox_file);
+ (void)close(spamd_sock);
+ return DEFER;
+ }
+
/* now we are connected to spamd on spamd_sock */
(void)string_format(spamd_buffer,
sizeof(spamd_buffer),
"spam acl condition: %s on spamd socket", strerror(errno));
else {
if (time(NULL) - start < SPAMD_TIMEOUT)
- goto again;
+ goto again;
log_write(0, LOG_MAIN|LOG_PANIC,
"spam acl condition: timed out writing spamd socket");
}