+rnd = random() % weights;
+
+for (i = 0; i < num_servers; i++)
+ if (!spamds[i]->is_failed && spamds[i]->is_backup == usebackup)
+ if ((rnd -= spamds[i]->weight) < 0)
+ return i;
+
+log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s unknown error (memory/cpu corruption?)", loglabel);
+return -1;
+}
+
+
+int
+spam(const uschar **listptr)
+{
+int sep = 0;
+const uschar *list = *listptr;
+uschar *user_name;
+uschar user_name_buffer[128];
+unsigned long mbox_size;
+FILE *mbox_file;
+int spamd_sock = -1;
+uschar spamd_buffer[32600];
+int i, j, offset, result;
+uschar spamd_version[8];
+uschar spamd_short_result[8];
+uschar spamd_score_char;
+double spamd_threshold, spamd_score, spamd_reject_score;
+int spamd_report_offset;
+uschar *p,*q;
+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 */
+struct timeval select_tv; /* and applied by PH */
+fd_set select_fd;
+#endif
+uschar *spamd_address_work;
+spamd_address_container * sd;
+
+/* stop compiler warning */
+result = 0;
+
+/* find the username from the option list */
+if ((user_name = string_nextinlist(&list, &sep,
+ user_name_buffer,
+ sizeof(user_name_buffer))) == NULL)
+ {
+ /* no username given, this means no scanning should be done */
+ return FAIL;
+ }
+
+/* if username is "0" or "false", do not scan */
+if ( (Ustrcmp(user_name,"0") == 0) ||
+ (strcmpic(user_name,US"false") == 0) )
+ return FAIL;
+
+/* if there is an additional option, check if it is "true" */
+if (strcmpic(list,US"true") == 0)
+ /* in that case, always return true later */
+ override = 1;
+
+/* expand spamd_address if needed */
+if (*spamd_address == '$')
+ {
+ spamd_address_work = expand_string(spamd_address);
+ if (spamd_address_work == NULL)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s spamd_address starts with $, but expansion failed: %s",
+ loglabel, expand_string_message);
+ return DEFER;