/* 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;
}