aboutsummaryrefslogtreecommitdiff
path: root/gacopyz
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-05-07 15:17:34 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-05-07 15:17:34 +0300
commit05a8bb0ca988f41f016420ffc7dde427e423c187 (patch)
treefff58297f073bec8148c2d5468a45d592eab0379 /gacopyz
parent9f8f65324491b4186f4fd3c2580a8e0b14a248d9 (diff)
downloadmailfromd-05a8bb0ca988f41f016420ffc7dde427e423c187.tar.gz
mailfromd-05a8bb0ca988f41f016420ffc7dde427e423c187.tar.bz2
Implement v6 negotiation on the server side.
* gacopyz/stagenames.c: New file. * gacopyz/Makefile.am (libgacopyz_a_SOURCES): Add stagenames.c. * gacopyz/gacopyz.c (gacopyz_context_loop): Free req_macros. (gacopyz_addrcpt_par): rename to gacopyz_add_rcpt_par. * gacopyz/gacopyz.h (SM_LM_VRS_MAJOR, SM_LM_VRS_MAJOR) (SM_LM_VRS_PLVL, GACOPYZ_SM_MKVER): New macros. (macro_index): Rename to gacopyz_stage. All uses updated. (smfi_version): New proto. (gacopyz_addrcpt_par): rename to gacopyz_add_rcpt_par. (gacopyz_stage_name): New declaration. (gacopyz_srv_get_required_macros): New proto. (gacopyz_srv_set_version, gacopyz_srv_set_protocol) (gacopyz_srv_set_actions): 2nd argument is unsigned long. * gacopyz/server.c (struct gacopyz_srv): New member req_macros. (gacopyz_srv_get_required_macros): New function. (gacopyz_srv_destroy): Free req_macros. (gacopyz_srv_negotiate): Read macros. * mfd/gram.y (milter_state_name): Removed. Use gacopyz_stage_name instead. * mtasim/mtasim.c: New options: --gacopyz-log, --milter-proto, --milter-acts. * doc/mtasim.texi, doc/mailfromd.texi: Update.
Diffstat (limited to 'gacopyz')
-rw-r--r--gacopyz/Makefile.am1
-rw-r--r--gacopyz/context.c4
-rw-r--r--gacopyz/gacopyz.c71
-rw-r--r--gacopyz/gacopyz.h58
-rw-r--r--gacopyz/gacopyz_priv.h4
-rw-r--r--gacopyz/server.c121
-rw-r--r--gacopyz/smfi.c17
-rw-r--r--gacopyz/stagenames.c27
8 files changed, 237 insertions, 66 deletions
diff --git a/gacopyz/Makefile.am b/gacopyz/Makefile.am
index 7d8c012b..d658b3e7 100644
--- a/gacopyz/Makefile.am
+++ b/gacopyz/Makefile.am
@@ -27,6 +27,7 @@ libgacopyz_a_SOURCES = \
mfapi.h\
proc.c\
server.c\
+ stagenames.c\
trans.h
EXTRA_DIST=trans.tab trans.awk
diff --git a/gacopyz/context.c b/gacopyz/context.c
index 41d64c44..12094fdf 100644
--- a/gacopyz/context.c
+++ b/gacopyz/context.c
@@ -1,5 +1,5 @@
/* This file is part of gacopyz.
- Copyright (C) 2006, 2007 Sergey Poznyakoff
+ Copyright (C) 2006, 2007, 2009 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
@@ -50,7 +50,7 @@ gacopyz_getsymval(SMFICTX *ctx, const char *name)
if (name[len-1] == '}')
len--;
- for (i = maci_max - 1; i >= 0; i--) {
+ for (i = gacopyz_stage_max - 1; i >= 0; i--) {
if (ctx->macros[i].argv) {
char **p;
diff --git a/gacopyz/gacopyz.c b/gacopyz/gacopyz.c
index f29681be..e26f7e2e 100644
--- a/gacopyz/gacopyz.c
+++ b/gacopyz/gacopyz.c
@@ -764,7 +764,7 @@ make_optneg_buf(SMFICTX *ctx, gacopyz_uint32_t *vbuf,
size_t bufsize = 0;
int i;
- for (i = 0; i < maci_max; i++) {
+ for (i = 0; i < gacopyz_stage_max; i++) {
if (ctx->req_macros[i])
bufsize += strlen(ctx->req_macros[i]) + 1 +
sizeof(gacopyz_uint32_t);
@@ -789,7 +789,7 @@ make_optneg_buf(SMFICTX *ctx, gacopyz_uint32_t *vbuf,
*pbuf = buf;
buf += OPTLEN;
- for (i = 0; i < maci_max; i++) {
+ for (i = 0; i < gacopyz_stage_max; i++) {
if (ctx->req_macros[i]) {
gacopyz_uint32_t v;
size_t len;
@@ -901,7 +901,7 @@ macro_assoc_free(macro_assoc_t *p)
static void
clear_macros(SMFICTX *ctx, int i)
{
- for (; i < maci_max; i++)
+ for (; i < gacopyz_stage_max; i++)
macro_assoc_free(&ctx->macros[i]);
}
@@ -962,7 +962,7 @@ shan_abort(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static state_ret_type
shan_macro(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
{
- enum macro_index ind;
+ enum gacopyz_stage ind;
char **p;
if (!arg->argv.v)
@@ -970,31 +970,31 @@ shan_macro(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
switch (arg->argv.cmd) {
case SMFIC_CONNECT:
- ind = maci_conn;
+ ind = gacopyz_stage_conn;
break;
case SMFIC_HELO:
- ind = maci_helo;
+ ind = gacopyz_stage_helo;
break;
case SMFIC_MAIL:
- ind = maci_mail;
+ ind = gacopyz_stage_mail;
break;
case SMFIC_RCPT:
- ind = maci_rcpt;
+ ind = gacopyz_stage_rcpt;
break;
case SMFIC_DATA:
- ind = maci_data;
+ ind = gacopyz_stage_data;
break;
case SMFIC_BODYEOB:
- ind = maci_eom;
+ ind = gacopyz_stage_eom;
break;
case SMFIC_EOH:
- ind = maci_eoh;
+ ind = gacopyz_stage_eoh;
break;
default:
@@ -1346,33 +1346,33 @@ shan_unkn(SMFICTX *ctx, union state_arg *arg, unsigned char *cmd)
static struct state_disp disp[] = {
{ SMFIC_ABORT, "abort",
- arg_no_args, shan_abort, st_abrt, CT_CNT, maci_none },
+ arg_no_args, shan_abort, st_abrt, CT_CNT, gacopyz_stage_none },
{ SMFIC_MACRO, "macro",
- arg_argvc, shan_macro, st_none, CT_CNT, maci_none },
+ arg_argvc, shan_macro, st_none, CT_CNT, gacopyz_stage_none },
{ SMFIC_BODY, "body",
- arg_one_string, shan_body, st_body, CT_CNT, maci_none },
+ arg_one_string, shan_body, st_body, CT_CNT, gacopyz_stage_none },
{ SMFIC_CONNECT, "connect",
- arg_two_strings, shan_connect, st_conn, CT_CLR, maci_conn },
+ arg_two_strings, shan_connect, st_conn, CT_CLR, gacopyz_stage_conn },
{ SMFIC_BODYEOB, "endm",
- arg_one_string, shan_endm, st_endm, CT_CNT, maci_eom },
+ arg_one_string, shan_endm, st_endm, CT_CNT, gacopyz_stage_eom },
{ SMFIC_HELO, "helo",
- arg_one_string, shan_helo, st_helo, CT_CLR, maci_helo },
+ arg_one_string, shan_helo, st_helo, CT_CLR, gacopyz_stage_helo },
{ SMFIC_HEADER, "header",
- arg_two_strings, shan_header, st_hdrs, CT_CNT, maci_none },
+ arg_two_strings, shan_header, st_hdrs, CT_CNT, gacopyz_stage_none },
{ SMFIC_MAIL, "mail",
- arg_argv, shan_mail, st_mail, CT_CLR, maci_mail },
+ arg_argv, shan_mail, st_mail, CT_CLR, gacopyz_stage_mail },
{ SMFIC_OPTNEG, "optneg",
- arg_ints, shan_optneg, st_opts, CT_CNT, maci_none },
+ arg_ints, shan_optneg, st_opts, CT_CNT, gacopyz_stage_none },
{ SMFIC_EOH, "eoh",
- arg_no_args, shan_eoh, st_eohs, CT_CNT, maci_none },
+ arg_no_args, shan_eoh, st_eohs, CT_CNT, gacopyz_stage_none },
{ SMFIC_QUIT, "quit",
- arg_no_args, shan_quit, st_quit, CT_END, maci_none },
+ arg_no_args, shan_quit, st_quit, CT_END, gacopyz_stage_none },
{ SMFIC_DATA, "data",
- arg_no_args, shan_data, st_data, CT_CNT, maci_none },
+ arg_no_args, shan_data, st_data, CT_CNT, gacopyz_stage_none },
{ SMFIC_RCPT, "rcpt",
- arg_argv, shan_rcpt, st_rcpt, CT_IGN|CT_CLR, maci_rcpt },
+ arg_argv, shan_rcpt, st_rcpt, CT_IGN|CT_CLR, gacopyz_stage_rcpt },
{ SMFIC_UNKNOWN, "unknown",
- arg_one_string, shan_unkn, st_unkn, CT_IGN|CT_CLR, maci_none }
+ arg_one_string, shan_unkn, st_unkn, CT_IGN|CT_CLR, gacopyz_stage_none }
};
struct state_disp *
@@ -1488,6 +1488,17 @@ report_command(enum state state, enum state next_state,
gacopyz_logdump(SMI_LOG_WARN, _("buffer"), buffer, size);
}
+static int
+ctx_free(SMFICTX *ctx)
+{
+ int i;
+
+ free(ctx->reply);
+ clear_macros(&ctx, 0);
+ for (i = 0; i < gacopyz_stage_max; i++)
+ free(ctx->req_macros[i]);
+}
+
int
gacopyz_context_loop(int fd, struct smfiDesc *desc)
{
@@ -1648,9 +1659,9 @@ gacopyz_context_loop(int fd, struct smfiDesc *desc)
free(buffer);
if (desc->xxfi_close)
desc->xxfi_close(&ctx);
- free(ctx.reply);
- clear_macros(&ctx, 0);
+ ctx_free(&ctx);
+
if (desc->xxfi_finish)
desc->xxfi_finish();
@@ -2026,7 +2037,7 @@ gacopyz_quarantine(SMFICTX *ctx, const char *reason)
}
int
-gacopyz_addrcpt_par(SMFICTX *ctx, const char *rcpt, const char *args)
+gacopyz_add_rcpt_par(SMFICTX *ctx, const char *rcpt, const char *args)
{
if (!rcpt || !*rcpt)
return MI_FAILURE;
@@ -2046,9 +2057,9 @@ gacopyz_chgfrom(SMFICTX *ctx, const char *from, const char *args)
}
int
-gacopyz_setsymlist(SMFICTX *ctx, enum macro_index ind, const char *macros)
+gacopyz_setsymlist(SMFICTX *ctx, enum gacopyz_stage ind, const char *macros)
{
- if (ind < 0 || ind >= maci_max)
+ if (ind < 0 || ind >= gacopyz_stage_max)
return MI_FAILURE;
if (ctx->req_macros[ind])
free(ctx->req_macros[ind]);
diff --git a/gacopyz/gacopyz.h b/gacopyz/gacopyz.h
index f0b5bff2..f7d547a7 100644
--- a/gacopyz/gacopyz.h
+++ b/gacopyz/gacopyz.h
@@ -48,6 +48,13 @@ extern "C" {
/* Implementation version number */
#define SMFI_VERSION 0x01000000
+#define SM_LM_VRS_MAJOR(v) (((v) & 0x7f000000) >> 24)
+#define SM_LM_VRS_MINOR(v) (((v) & 0x007fff00) >> 8)
+#define SM_LM_VRS_PLVL(v) ((v) & 0x0000007f)
+
+#define GACOPYZ_SM_MKVER(maj,min,pat) \
+ ((((maj) & 0x7f)<<24) | (((min) & 0x7ffff) << 8) | ((pat) & 0x7f))
+
/* Milter protocol version */
#define SMFI_PROT_VERSION 6
@@ -199,26 +206,26 @@ typedef union {
struct sockaddr_un sunix;
} milter_sockaddr_t;
-enum macro_index {
- maci_conn,
- maci_helo,
- maci_mail,
- maci_rcpt,
- maci_data,
- maci_eom,
- maci_eoh,
+enum gacopyz_stage {
+ gacopyz_stage_conn,
+ gacopyz_stage_helo,
+ gacopyz_stage_mail,
+ gacopyz_stage_rcpt,
+ gacopyz_stage_data,
+ gacopyz_stage_eom,
+ gacopyz_stage_eoh,
- maci_max,
- maci_none = maci_max
+ gacopyz_stage_max,
+ gacopyz_stage_none = gacopyz_stage_max
};
-#define SMFIM_CONNECT maci_conn
-#define SMFIM_HELO maci_helo
-#define SMFIM_ENVFROM maci_mail
-#define SMFIM_ENVRCPT maci_rcpt
-#define SMFIM_DATA maci_data
-#define SMFIM_EOM maci_eom
-#define SMFIM_EOH maci_eoh
+#define SMFIM_CONNECT gacopyz_stage_conn
+#define SMFIM_HELO gacopyz_stage_helo
+#define SMFIM_ENVFROM gacopyz_stage_mail
+#define SMFIM_ENVRCPT gacopyz_stage_rcpt
+#define SMFIM_DATA gacopyz_stage_data
+#define SMFIM_EOM gacopyz_stage_eom
+#define SMFIM_EOH gacopyz_stage_eoh
#define _SOCK_ADDR milter_sockaddr_t
#define smfiDesc gacopyz_milter_descr
@@ -275,6 +282,7 @@ struct gacopyz_milter_descr
};
/* Standard API calls */
+extern int smfi_version (unsigned int *, unsigned int *, unsigned int *);
extern int smfi_opensocket (int);
extern int smfi_register (struct smfiDesc);
extern int smfi_main (void);
@@ -365,15 +373,17 @@ int gacopyz_replace_body(SMFICTX *ctx, const unsigned char *bodyp,
size_t bodylen);
int gacopyz_progress(SMFICTX *ctx);
int gacopyz_quarantine(SMFICTX *ctx, const char *reason);
-int gacopyz_addrcpt_par(SMFICTX *ctx, const char *rcpt, const char *args);
+int gacopyz_add_rcpt_par(SMFICTX *ctx, const char *rcpt, const char *args);
int gacopyz_chgfrom(SMFICTX *ctx, const char *from, const char *args);
-int gacopyz_setsymlist(SMFICTX *ctx, enum macro_index ind, const char *macros);
+int gacopyz_setsymlist(SMFICTX *ctx, enum gacopyz_stage ind, const char *macros);
int gacopyz_setpriv (SMFICTX *ctx, void *data);
void *gacopyz_getpriv (SMFICTX *ctx);
/* Logging (extensions) */
+extern const char *gacopyz_stage_name[gacopyz_stage_max];
+
#define GACOPYZ_VBUFSIZE 69
size_t gacopyz_format_vbuf(char vbuf[GACOPYZ_VBUFSIZE], const char *buf,
size_t size);
@@ -411,6 +421,10 @@ void gacopyz_srv_iterate_macros (gacopyz_srv_t srv,
void *data),
void *data);
void gacopyz_srv_count_macros (gacopyz_srv_t srv, size_t *count);
+
+const char **gacopyz_srv_get_required_macros(gacopyz_srv_t srv,
+ enum gacopyz_stage stage);
+
int gacopyz_srv_connect (gacopyz_srv_t srv);
int gacopyz_srv_init(gacopyz_srv_t srv);
int gacopyz_srv_negotiate(gacopyz_srv_t srv);
@@ -440,9 +454,9 @@ void gacopyz_srv_set_callback(gacopyz_srv_t srv,
void gacopyz_srv_set_callback_data(gacopyz_srv_t, void *);
int gacopyz_srv_set_source(gacopyz_srv_t srv, unsigned long addr);
-int gacopyz_srv_set_version(gacopyz_srv_t srv, int version);
-int gacopyz_srv_set_protocol(gacopyz_srv_t srv, int proto);
-int gacopyz_srv_set_actions(gacopyz_srv_t srv, int acts);
+int gacopyz_srv_set_version(gacopyz_srv_t srv, unsigned long version);
+int gacopyz_srv_set_protocol(gacopyz_srv_t srv, unsigned long proto);
+int gacopyz_srv_set_actions(gacopyz_srv_t srv, unsigned long acts);
#define GACOPYZ_WRITE_TIMEOUT 10
#define GACOPYZ_READ_TIMEOUT 10
diff --git a/gacopyz/gacopyz_priv.h b/gacopyz/gacopyz_priv.h
index 76be1611..d7e1ffe9 100644
--- a/gacopyz/gacopyz_priv.h
+++ b/gacopyz/gacopyz_priv.h
@@ -34,8 +34,8 @@ struct smfi_str {
unsigned long mta_pflags; /* pflags supported by MTA */
unsigned long aflags; /* milter action flags (from xxfi_flags) */
int nmacros; /* Number of entries in macros */
- macro_assoc_t macros[maci_max]; /* Macro tables */
- char *req_macros[maci_max]; /* Required macros */
+ macro_assoc_t macros[gacopyz_stage_max]; /* Macro tables */
+ char *req_macros[gacopyz_stage_max]; /* Required macros */
char *reply; /* reply code */
void *privdata; /* private data */
};
diff --git a/gacopyz/server.c b/gacopyz/server.c
index a61836e8..e7cfa643 100644
--- a/gacopyz/server.c
+++ b/gacopyz/server.c
@@ -1,5 +1,5 @@
/* This file is part of gacopyz.
- Copyright (C) 2007, 2008 Sergey Poznyakoff
+ Copyright (C) 2007, 2008, 2009 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
@@ -49,6 +49,7 @@ struct gacopyz_srv {
unsigned long version;
unsigned long acts;
unsigned long proto;
+ char **req_macros[gacopyz_stage_max]; /* Required macros */
int (*cb_reply) (gacopyz_srv_t srv, int cmd, int rcmd, void *data);
void *cb_data;
@@ -279,6 +280,13 @@ gacopyz_srv_count_macros(gacopyz_srv_t srv, size_t *count)
}
+const char **
+gacopyz_srv_get_required_macros(gacopyz_srv_t srv, enum gacopyz_stage stage)
+{
+ return (const char **) srv->req_macros[stage];
+}
+
+
struct timeval default_gacopyz_timeout[GACOPYZ_TO_COUNT] = {
{ GACOPYZ_WRITE_TIMEOUT, 0 },
@@ -612,7 +620,7 @@ gacopyz_srv_set_source(gacopyz_srv_t srv, unsigned long addr)
}
int
-gacopyz_srv_set_version(gacopyz_srv_t srv, int version)
+gacopyz_srv_set_version(gacopyz_srv_t srv, unsigned long version)
{
GACOPYZ_ASSERT(srv);
@@ -621,7 +629,7 @@ gacopyz_srv_set_version(gacopyz_srv_t srv, int version)
}
int
-gacopyz_srv_set_protocol(gacopyz_srv_t srv, int proto)
+gacopyz_srv_set_protocol(gacopyz_srv_t srv, unsigned long proto)
{
GACOPYZ_ASSERT(srv);
@@ -630,7 +638,7 @@ gacopyz_srv_set_protocol(gacopyz_srv_t srv, int proto)
}
int
-gacopyz_srv_set_actions(gacopyz_srv_t srv, int acts)
+gacopyz_srv_set_actions(gacopyz_srv_t srv, unsigned long acts)
{
GACOPYZ_ASSERT(srv);
@@ -638,15 +646,24 @@ gacopyz_srv_set_actions(gacopyz_srv_t srv, int acts)
return MI_SUCCESS;
}
-
void
gacopyz_srv_destroy(gacopyz_srv_t *p)
{
+ int i;
+
gacopyz_srv_t srv = *p;
gacopyz_srv_clear_macros(srv);
free(srv->portspec);
free(srv->id);
free(srv->def);
+ for (i = 0; i < gacopyz_stage_max; i++)
+ if (srv->req_macros[i]) {
+ int j;
+
+ for (j = 0; srv->req_macros[i][j]; j++)
+ free(srv->req_macros[i][j]);
+ free(srv->req_macros[i]);
+ }
free(srv->buf);
free(srv);
*p = 0;
@@ -860,6 +877,94 @@ gacopyz_srv_connect(gacopyz_srv_t srv)
return MI_SUCCESS;
}
+#define ISWS(c) ((c) == ' ' || (c) == '\t')
+
+static void
+parse_macros(gacopyz_srv_t srv, enum gacopyz_stage stage, char *buf)
+{
+ char *p;
+ char **argv;
+ size_t count;
+
+ count = 0;
+ for (p = buf; *p;) {
+ while (*p && ISWS(*p))
+ p++;
+ if (*p) {
+ count++;
+ while (*p && !ISWS(*p))
+ p++;
+ }
+ }
+ if (count == 0)
+ return;
+ GACOPYZ_ALLOC(srv, argv = calloc(count + 1, sizeof(argv[0])));
+ count = 0;
+ for (p = buf; *p;) {
+ while (*p && ISWS(*p))
+ p++;
+ if (*p) {
+ size_t i;
+ char *str = p;
+
+ for (i = 0; *p && !ISWS(*p); p++, i++)
+ ;
+ if (i > 0) {
+ char *newstr;
+
+ if (*str == '{' && str[i-1] == '}') {
+ str++;
+ i -= 2;
+ }
+ GACOPYZ_ALLOC(srv, newstr = malloc(i + 1));
+ memcpy(newstr, str, i);
+ newstr[i] = 0;
+ argv[count++] = newstr;
+ }
+ }
+ }
+ argv[count] = NULL;
+ srv->req_macros[stage] = argv;
+}
+
+
+static void
+read_macros(gacopyz_srv_t srv)
+{
+ char *buf = srv->buf + 3 * sizeof(gacopyz_uint32_t);
+ size_t size = srv->bufsize - 3 * sizeof(gacopyz_uint32_t);
+
+ while (size > sizeof(gacopyz_uint32_t)) {
+ gacopyz_uint32_t v;
+ unsigned n;
+ size_t len;
+
+ memcpy (&v, buf, sizeof(gacopyz_uint32_t));
+ n = ntohl(v);
+ if (n >= gacopyz_stage_max) {
+ gacopyz_io_log(&srv->iod, SMI_LOG_ERR,
+ _("received invalid stage number"));
+ break;
+ }
+ buf += sizeof(gacopyz_uint32_t);
+ size -= sizeof(gacopyz_uint32_t);
+ if (size == 0)
+ break;
+ len = strlen(buf) + 1;
+ if (len > size) {
+ gacopyz_io_log(&srv->iod, SMI_LOG_ERR,
+ _("invalid macro list"));
+ break;
+ }
+ gacopyz_io_log(&srv->iod, SMI_LOG_DEBUG,
+ _("macros for stage \"%s\" (%d): %s"),
+ gacopyz_stage_name[n], n, buf);
+ parse_macros(srv, n, buf);
+ buf += len;
+ size -= len;
+ }
+}
+
int
gacopyz_srv_negotiate(gacopyz_srv_t srv)
{
@@ -927,6 +1032,10 @@ gacopyz_srv_negotiate(gacopyz_srv_t srv)
return MI_FAILURE;
}
+ if (milter_version > 3
+ && srv->bufsize > 3 * sizeof(gacopyz_uint32_t))
+ read_macros(srv);
+
srv->version = milter_version;
srv->acts = milter_acts;
srv->proto = milter_proto;
@@ -1209,8 +1318,6 @@ gacopyz_srv_conn(gacopyz_srv_t srv, const char *hostname, struct sockaddr *sa)
int
gacopyz_srv_helo(gacopyz_srv_t srv, const char *domain)
{
- int rc;
-
GACOPYZ_ASSERT(srv);
if (srv->state == srv_msgproc)
gacopyz_srv_abort(srv);
diff --git a/gacopyz/smfi.c b/gacopyz/smfi.c
index 721b3460..4f8628d4 100644
--- a/gacopyz/smfi.c
+++ b/gacopyz/smfi.c
@@ -197,7 +197,7 @@ smfi_quarantine(SMFICTX *ctx, char *reason)
int
smfi_addrcpt_par(SMFICTX *ctx, char *rcpt, char *args)
{
- return gacopyz_addrcpt_par(ctx, rcpt, args);
+ return gacopyz_add_rcpt_par(ctx, rcpt, args);
}
int
@@ -209,12 +209,23 @@ smfi_chgfrom(SMFICTX *ctx, char *from, char *args)
int
smfi_setsymlist(SMFICTX *ctx, int n, char *macros)
{
- if (n < 0 || n >= maci_max)
+ 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;
+}
+
diff --git a/gacopyz/stagenames.c b/gacopyz/stagenames.c
new file mode 100644
index 00000000..0be67617
--- /dev/null
+++ b/gacopyz/stagenames.c
@@ -0,0 +1,27 @@
+/* This file is part of gacopyz.
+ Copyright (C) 2009 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 <http://www.gnu.org/licenses/>. */
+
+#include <gacopyz_priv.h>
+
+const char *gacopyz_stage_name[gacopyz_stage_max] = {
+ "connect",
+ "helo",
+ "envfrom",
+ "envrcpt",
+ "data",
+ "eom",
+ "eoh"
+};

Return to:

Send suggestions and report system problems to the System administrator.