void dupe_action(SMFICTX *ctx, mlfiPriv *priv) { if(ctx != NULL && priv != NULL && priv->pdupercpt != NULL) { smfi_addrcpt(ctx, priv->pdupercpt); free(priv->pdupercpt); priv->pdupercpt = NULL; } }
static sfsistat test_eom(SMFICTX *ctx) { printf("test_eom\n"); #ifdef SMFIR_REPLBODY if (body_file) { char buf[BUFSIZ + 2]; FILE *fp; size_t len; int count; if ((fp = fopen(body_file, "r")) == 0) { perror(body_file); } else { printf("replace body with content of %s\n", body_file); for (count = 0; fgets(buf, BUFSIZ, fp) != 0; count++) { len = strcspn(buf, "\n"); buf[len + 0] = '\r'; buf[len + 1] = '\n'; if (smfi_replacebody(ctx, buf, len + 2) == MI_FAILURE) { fprintf(stderr, "body replace failure\n"); exit(1); } if (verbose) printf("%.*s\n", (int) len, buf); } if (count == 0) perror("fgets"); (void) fclose(fp); } } #endif #ifdef SMFIR_CHGFROM if (chg_from != 0 && smfi_chgfrom(ctx, chg_from, "whatever") == MI_FAILURE) fprintf(stderr, "smfi_chgfrom failed\n"); #endif #ifdef SMFIR_INSHEADER if (ins_hdr && smfi_insheader(ctx, ins_idx, ins_hdr, ins_val) == MI_FAILURE) fprintf(stderr, "smfi_insheader failed\n"); #endif #ifdef SMFIR_CHGHEADER if (chg_hdr && smfi_chgheader(ctx, chg_hdr, chg_idx, chg_val) == MI_FAILURE) fprintf(stderr, "smfi_chgheader failed\n"); #endif { int count; for (count = 0; count < rcpt_count; count++) if (smfi_addrcpt(ctx, rcpt_addr[count]) == MI_FAILURE) fprintf(stderr, "smfi_addrcpt `%s' failed\n", rcpt_addr[count]); } return (test_reply(ctx, test_eom_reply)); }
int msgmod_add_rcpt(void *ctx, int argc, var_t *args[]) { char *rcpt; char *esmtp_args = NULL; int r; if (argc < 1 || argc > 2) { log_error("msgmod_add_rcpt: bad argument count"); return -1; } rcpt = args[0]->v_data; if (argc == 2) { esmtp_args = args[1]->v_data; r = smfi_addrcpt_par(ctx, rcpt, esmtp_args); } else { r = smfi_addrcpt(ctx, rcpt); } if (r != MI_SUCCESS) { log_error("msgmod_add_rcpt: smfi_addrcpt failed"); return -1; } log_debug("msgmod_add_rcpt: %s %s", rcpt, esmtp_args? esmtp_args: ""); return 0; }
int spamdscan(SMFICTX *ctx, struct mlfi_priv *priv, struct config_file *cfg, char **subject, int extra) { int retry, r = -2, hr = 0, to_trace = 0; struct timeval t; double ts, tf; struct spamd_server *selected = NULL; char rbuf[BUFSIZ], hdrbuf[BUFSIZ]; char *prefix = "s", *mid = NULL, *c; rspamd_result_t res; struct rspamd_metric_result *cur = NULL, *tmp; struct rspamd_symbol *cur_symbol, *tmp_symbol; enum rspamd_metric_action res_action = METRIC_ACTION_NOACTION; struct timespec sleep_ts; gettimeofday(&t, NULL); ts = t.tv_sec + t.tv_usec / 1000000.0; retry = cfg->spamd_retry_count; sleep_ts.tv_sec = cfg->spamd_retry_timeout / 1000; sleep_ts.tv_nsec = (cfg->spamd_retry_timeout % 1000) * 1000000ULL; TAILQ_INIT(&res); /* try to scan with available servers */ while (1) { if (extra) { selected = (struct spamd_server *) get_random_upstream ((void *)cfg->extra_spamd_servers, cfg->extra_spamd_servers_num, sizeof (struct spamd_server), t.tv_sec, cfg->spamd_error_time, cfg->spamd_dead_time, cfg->spamd_maxerrors); } else { selected = (struct spamd_server *) get_random_upstream ((void *)cfg->spamd_servers, cfg->spamd_servers_num, sizeof (struct spamd_server), t.tv_sec, cfg->spamd_error_time, cfg->spamd_dead_time, cfg->spamd_maxerrors); } if (selected == NULL) { msg_err ("spamdscan: upstream get error, %s", priv->file); return -1; } if (selected->type == SPAMD_SPAMASSASSIN) { prefix = "s"; r = spamdscan_socket (priv->file, selected, cfg, &res); } else { prefix = "rs"; r = rspamdscan_socket (ctx, priv, selected, cfg, &res, &mid); } if (r == 0 || r == 1) { upstream_ok (&selected->up, t.tv_sec); break; } upstream_fail (&selected->up, t.tv_sec); if (r == -2) { msg_warn("%spamdscan: unexpected problem, %s, %s", prefix, selected->name, priv->file); break; } if (--retry < 1) { msg_warn("%spamdscan: retry limit exceeded, %s, %s", prefix, selected->name, priv->file); break; } msg_warn("%spamdscan: failed to scan, retry, %s, %s", prefix, selected->name, priv->file); nanosleep (&sleep_ts, NULL); } /* * print scanning time, server and result */ gettimeofday(&t, NULL); tf = t.tv_sec + t.tv_usec / 1000000.0; /* Parse res tailq */ cur = TAILQ_FIRST(&res); while (cur) { if (cur->metric_name) { if (cfg->extended_spam_headers) { hr = snprintf (hdrbuf, sizeof (hdrbuf), "%s: %s [%.2f / %.2f]%c", cur->metric_name, cur->score > cur->required_score ? "True" : "False", cur->score, cur->required_score, TAILQ_FIRST(&cur->symbols) != NULL ? '\n' : ' '); } r = snprintf (rbuf, sizeof (rbuf), "spamdscan: scan qid: <%s>, mid: <%s>, %f, %s, metric: %s: [%f / %f], symbols: ", priv->mlfi_id, (mid != NULL) ? mid : "undef", tf - ts, selected->name, cur->metric_name, cur->score, cur->required_score); free (cur->metric_name); } else { if (cfg->extended_spam_headers) { hr = snprintf (hdrbuf, sizeof (hdrbuf), "%s: %s [%.2f / %.2f]%c", "default", cur->score > cur->required_score ? "True" : "False", cur->score, cur->required_score, TAILQ_FIRST(&cur->symbols) != NULL ? '\n' : ' '); } r = snprintf (rbuf, sizeof (rbuf), "spamdscan: scan <%s>, %f, %s, metric: default: [%f / %f], symbols: ", priv->mlfi_id, tf - ts, selected->name, cur->score, cur->required_score); } if (cur->action > res_action) { res_action = cur->action; if (res_action == METRIC_ACTION_REWRITE_SUBJECT && cur->subject != NULL) { /* Copy subject as it would be freed further */ if (*subject != NULL) { free (*subject); } *subject = strdup (cur->subject); } } /* Write symbols */ cur_symbol = TAILQ_FIRST(&cur->symbols); if (cur_symbol == NULL) { r += snprintf (rbuf + r, sizeof (rbuf) - r, "no symbols"); } else { while (cur_symbol) { if (cur_symbol->symbol) { if (TAILQ_NEXT (cur_symbol, entry)) { r += snprintf (rbuf + r, sizeof (rbuf) - r, "%s, ", cur_symbol->symbol); } else { r += snprintf (rbuf + r, sizeof (rbuf) - r, "%s", cur_symbol->symbol); } if (cfg->trace_symbol) { c = strchr (cur_symbol->symbol, '('); if (c != NULL) { *c = '\0'; } if ( !strcmp (cfg->trace_symbol, cur_symbol->symbol)) { to_trace ++; } } if (cfg->extended_spam_headers) { if (TAILQ_NEXT (cur_symbol, entry)) { hr += snprintf (hdrbuf + hr, sizeof (hdrbuf) - hr, " %s\n", cur_symbol->symbol); } else { hr += snprintf (hdrbuf + hr, sizeof (hdrbuf) - hr, " %s", cur_symbol->symbol); } } free (cur_symbol->symbol); } tmp_symbol = cur_symbol; cur_symbol = TAILQ_NEXT(cur_symbol, entry); free (tmp_symbol); } } msg_info ("%s", rbuf); if (cur->subject != NULL) { free (cur->subject); } tmp = cur; cur = TAILQ_NEXT(cur, entry); free (tmp); if (cfg->extended_spam_headers) { if (extra) { smfi_addheader (ctx, "X-Spamd-Extra-Result", hdrbuf); } else { smfi_addheader (ctx, "X-Spamd-Result", hdrbuf); } } } /* All other statistic headers */ if (cfg->extended_spam_headers) { if (extra) { smfi_addheader (ctx, "X-Spamd-Extra-Server", selected->name); snprintf (hdrbuf, sizeof (hdrbuf), "%.2f", tf - ts); smfi_addheader (ctx, "X-Spamd-Extra-Scan-Time", hdrbuf); } else { smfi_addheader (ctx, "X-Spamd-Server", selected->name); snprintf (hdrbuf, sizeof (hdrbuf), "%.2f", tf - ts); smfi_addheader (ctx, "X-Spamd-Scan-Time", hdrbuf); smfi_addheader (ctx, "X-Spamd-Queue-ID", priv->mlfi_id); } } /* Trace spam messages to specific addr */ if (!extra && to_trace && cfg->trace_addr) { smfi_addrcpt (ctx, cfg->trace_addr); smfi_setpriv (ctx, priv); } return (r > 0 ? res_action : r); }