/* This file is part of gacopyz. Copyright (C) 2006-2020 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include static int __smfi_dbg_level = 0; static int __smfi_logmask = 0; static time_t __smfi_timeout = 7210; static int __smfi_backlog = 1; static char *__smfi_conn = NULL; static gacopyz_conn_t milter_conn; int smfi_setdbg(int level) { __smfi_dbg_level = level; return MI_SUCCESS; } int smfi_setlogmask(int logmask) { __smfi_logmask = logmask; return MI_SUCCESS; } int smfi_settimeout(time_t to) { __smfi_timeout = to; return MI_SUCCESS; } int smfi_setbacklog(int val) { if (val <= 0) return MI_FAILURE; __smfi_backlog = val; return MI_SUCCESS; } int smfi_set_foreground(int val) { return gacopyz_set_foreground(milter_conn, val); } int smfi_register(struct smfiDesc desc) { struct timeval t; if (gacopyz_init(&milter_conn, &desc)) return MI_FAILURE; if (__smfi_logmask) gacopyz_set_logmask(milter_conn, __smfi_logmask); if (__smfi_dbg_level) { int mask; gacopyz_get_logmask(milter_conn, &mask); gacopyz_set_logmask(milter_conn, mask | SMI_LOG_MASK(SMI_LOG_DEBUG)); } t.tv_usec = 0; t.tv_sec = __smfi_timeout; gacopyz_set_ctx_timeout(milter_conn, &t); return MI_SUCCESS; } int smfi_opensocket(int rmsock) { return gacopyz_open(milter_conn, __smfi_conn, __smfi_backlog, rmsock); } int smfi_setconn(char *conn) { if (!conn || !*conn) return MI_FAILURE; __smfi_conn = strdup(conn); if (!__smfi_conn) return MI_FAILURE; return MI_SUCCESS; } int smfi_main() { gacopyz_setup_signals(); if (!milter_conn) { gacopyz_log(SMI_LOG_ERR, _("connection not initialized")); return MI_FAILURE; } if (milter_conn->sd == -1 && gacopyz_open(milter_conn, __smfi_conn, __smfi_backlog, 0) == -1) { return MI_FAILURE; } return gacopyz_run(milter_conn); } int smfi_stop() { return gacopyz_stop(milter_conn); } int smfi_setreply(SMFICTX *ctx, char *rcode, char *xcode, char *message) { if (message && strpbrk(message, "\r\n")) return MI_FAILURE; return gacopyz_setreply(ctx, rcode, xcode, message); } int smfi_setmlreply(SMFICTX *ctx, const char *rcode, const char *xcode, ...) { int rc; va_list ap; va_start(ap, xcode); rc = _gacopyz_setmlreply_va(ctx, 32, rcode, xcode, ap); va_end(ap); return rc; } size_t smfi_setmaxdatasize (size_t s) { return ~((size_t)0); } int smfi_addheader(SMFICTX *ctx, char *headerf, char *headerv) { return gacopyz_add_header(ctx, headerf, headerv); } int smfi_insheader(SMFICTX *ctx, int index, char *headerf, char *headerv) { return gacopyz_insert_header(ctx, index, headerf, headerv); } int smfi_chgheader(SMFICTX *ctx, char *headerf, int index, char *headerv) { return gacopyz_change_header(ctx, index, headerf, headerv); } int smfi_addrcpt(SMFICTX *ctx, char *rcpt) { return gacopyz_add_rcpt(ctx, rcpt); } int smfi_delrcpt(SMFICTX *ctx, char *rcpt) { return gacopyz_del_rcpt(ctx, rcpt); } int smfi_replacebody(SMFICTX *ctx, unsigned char *bodyp, int bodylen) { return gacopyz_replace_body(ctx, bodyp, bodylen); } int smfi_progress(SMFICTX *ctx) { return gacopyz_progress(ctx); } int smfi_quarantine(SMFICTX *ctx, char *reason) { return gacopyz_quarantine(ctx, reason); } int smfi_addrcpt_par(SMFICTX *ctx, char *rcpt, char *args) { return gacopyz_add_rcpt_par(ctx, rcpt, args); } int smfi_chgfrom(SMFICTX *ctx, char *from, char *args) { return gacopyz_chgfrom(ctx, from, args); } int smfi_setsymlist(SMFICTX *ctx, int n, char *macros) { if (n < 0 || n >= gacopyz_stage_max) return MI_FAILURE; if (!macros || !*macros || ctx->req_macros[n]) return MI_FAILURE; return gacopyz_setsymlist(ctx, n, macros); } int smfi_version(unsigned int *maj, unsigned int *min, unsigned int *pat) { if (maj) *maj = SM_LM_VRS_MAJOR(SMFI_VERSION); if (min) *min = SM_LM_VRS_MINOR(SMFI_VERSION); if (pat) *pat = SM_LM_VRS_MINOR(SMFI_VERSION); return MI_SUCCESS; }