X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/6296a393aeab9fecc38916dfcbf1c94d54691650..1d28cc061677bd07d9bed48dd84bd5c590247043:/src/src/spam.c diff --git a/src/src/spam.c b/src/src/spam.c index b0e24b368..401fdb269 100644 --- a/src/src/spam.c +++ b/src/src/spam.c @@ -2,9 +2,11 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Tom Kistner 2003 - 2015 +/* + * Copyright (c) The Exim Maintainers 2016 - 2022 + * Copyright (c) Tom Kistner 2003 - 2015 * License: GPL - * Copyright (c) The Exim Maintainers 2016 - 2020 + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for calling spamassassin's spamd. Called from acl.c. */ @@ -35,7 +37,7 @@ spamd->is_failed = FALSE; spamd->weight = SPAMD_WEIGHT; spamd->timeout = SPAMD_TIMEOUT; spamd->retry = 0; -spamd->priority = 1; +spamd->priority = SPAMD_PRIORITY; return 0; } @@ -139,21 +141,11 @@ unsigned int i; spamd_address_container * sd; long weights; unsigned pri; -static BOOL srandomed = FALSE; /* speedup, if we have only 1 server */ if (num_servers == 1) return (spamds[0]->is_failed ? -1 : 0); -/* init ranmod */ -if (!srandomed) - { - struct timeval tv; - gettimeofday(&tv, NULL); - srandom((unsigned int)(tv.tv_usec/1000)); - srandomed = TRUE; - } - /* scan for highest pri */ for (pri = 0, i = 0; i < num_servers; i++) { @@ -170,7 +162,7 @@ for (weights = 0, i = 0; i < num_servers; i++) if (weights == 0) /* all servers failed */ return -1; -for (long rnd = random() % weights, i = 0; i < num_servers; i++) +for (long rnd = random_number(weights), i = 0; i < num_servers; i++) { sd = spamds[i]; if (!sd->is_failed && sd->priority == pri) @@ -204,12 +196,6 @@ uschar *p,*q; int override = 0; time_t start; size_t read, wrote; -#ifndef NO_POLL_H -struct pollfd pollfd; -#else /* Patch posted by Erik ? for OS X */ -struct timeval select_tv; /* and applied by PH */ -fd_set select_fd; -#endif uschar *spamd_address_work; spamd_address_container * sd; @@ -285,7 +271,7 @@ start = time(NULL); uschar * s; DEBUG(D_acl) debug_printf_indent("spamd: addr entry '%s'\n", address); - sd = store_get(sizeof(spamd_address_container), FALSE); + sd = store_get(sizeof(spamd_address_container), GET_UNTAINTED); for (sublist = address, args = 0, spamd_param_init(sd); (s = string_nextinlist(&sublist, &sublist_sep, NULL, 0)); @@ -405,19 +391,19 @@ if (wrote == -1) } /* now send the file */ -/* spamd sometimes accepts connections but doesn't read data off - * the connection. We make the file descriptor non-blocking so - * that the write will only write sufficient data without blocking - * and we poll the descriptor to make sure that we can write without - * blocking. Short writes are gracefully handled and if the whole - * transaction takes too long it is aborted. - * Note: poll() is not supported in OSX 10.2 and is reported to be - * broken in more recent versions (up to 10.4). +/* spamd sometimes accepts connections but doesn't read data off the connection. +We make the file descriptor non-blocking so that the write will only write +sufficient data without blocking and we poll the descriptor to make sure that we +can write without blocking. Short writes are gracefully handled and if the +whole transaction takes too long it is aborted. + +Note: poll() is not supported in OSX 10.2 and is reported to be broken in more + recent versions (up to 10.4). Workaround using select() removed 2021/11 (jgh). */ -#ifndef NO_POLL_H -pollfd.fd = spamd_cctx.sock; -pollfd.events = POLLOUT; +#ifdef NO_POLL_H +# error Need poll(2) support #endif + (void)fcntl(spamd_cctx.sock, F_SETFL, O_NONBLOCK); do { @@ -426,19 +412,7 @@ do { offset = 0; again: -#ifndef NO_POLL_H - result = poll(&pollfd, 1, 1000); - -/* Patch posted by Erik ? for OS X and applied by PH */ -#else - select_tv.tv_sec = 1; - select_tv.tv_usec = 0; - FD_ZERO(&select_fd); - FD_SET(spamd_cctx.sock, &select_fd); - result = select(spamd_cctx.sock+1, NULL, &select_fd, NULL, &select_tv); -#endif -/* End Erik's patch */ - + result = poll_one_fd(spamd_cctx.sock, POLLOUT, 1000); if (result == -1 && errno == EINTR) goto again; else if (result < 1)