aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2006-10-27 07:04:15 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2006-10-27 07:04:15 +0000
commit7ff7cd229dc9a481eea012329bafcc9d676b352b (patch)
treeef98a1ed54194f9cd44c526e60d9aa552a9d443b /src/main.c
parentc7835aa508b47cbfdb2ae4f952176c92714bfd71 (diff)
downloadmailfromd-7ff7cd229dc9a481eea012329bafcc9d676b352b.tar.gz
mailfromd-7ff7cd229dc9a481eea012329bafcc9d676b352b.tar.bz2
Move all milter-related stuff to engine.c
git-svn-id: file:///svnroot/mailfromd/trunk@657 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c1058
1 files changed, 1 insertions, 1057 deletions
diff --git a/src/main.c b/src/main.c
index 12a22a56..464fb966 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,9 +25,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
-#define obstack_chunk_alloc malloc
-#define obstack_chunk_free free
-#include <obstack.h>
#include <syslog.h>
#include <signal.h>
#include <pwd.h>
@@ -40,7 +37,6 @@
#include <mailutils/mailutils.h>
#include <mailutils/argp.h>
-#include <mailutils/daemon.h>
#include <mailutils/locker.h>
#include <libmilter/mfapi.h>
@@ -112,132 +108,6 @@ unsigned io_timeout = 3;
unsigned io_attempts = 3;
-static char *ctx_getsym(void *data, char *str);
-static int ctx_setreply(void *data, char *code, char *xcode, char *message);
-static void ctx_setheader(void *data, struct header_node *hdr);
-
-/* Per-message data */
-struct smtp_io_data; /* Declared later on */
-struct message_data {
- eval_environ_t env;
- struct smtp_io_data *io;
- mu_list_t hdr;
- char *helostr;
- char msgid[64];
-};
-
-#define MLFIPRIV(ctx) ((struct message_data*) smfi_getpriv(ctx))
-
-static struct message_data *
-priv_get(SMFICTX *ctx)
-{
- struct message_data *md = MLFIPRIV(ctx);
- if (!md) {
- md = malloc(sizeof(*md));
- if (!md)
- mu_error("not enough memory");
- else {
- md->env = create_environment(ctx,
- ctx_getsym,
- ctx_setreply,
- ctx_setheader,
- ctx);
- clear_rcpt_count(md->env);
- md->hdr = NULL;
- md->io = NULL;
- md->helostr = NULL;
- md->msgid[0] = 0;
- smfi_setpriv(ctx, md);
- }
- }
- if (!md->msgid[0]) {
- char *p = smfi_getsymval(ctx, "i");
- if (p) {
- size_t len = strlen(p);
- if (len > sizeof md->msgid - 3)
- len = sizeof md->msgid - 3;
- memcpy(md->msgid, p, len);
- md->msgid[len++] = ':';
- md->msgid[len++] = ' ';
- md->msgid[len] = 0;
- }
- }
- return md;
-}
-
-static int
-priv_set_io(SMFICTX *ctx, struct smtp_io_data *io)
-{
- struct message_data *md = priv_get(ctx);
- if (!md)
- return 1;
- md->io = io;
- return 0;
-}
-
-const char *
-mailfromd_msgid(SMFICTX *ctx)
-{
- struct message_data *md = priv_get(ctx);
- return md->msgid;
-}
-
-char *
-mailfromd_timestr(time_t timestamp, char *timebuf, size_t bufsize)
-{
- struct tm tm;
- gmtime_r(&timestamp, &tm);
- strftime(timebuf, bufsize, "%c", &tm);
- return timebuf;
-}
-
-int
-priv_store_header_command(SMFICTX *ctx, struct header_node *node)
-{
- struct message_data *md = priv_get(ctx);
- if (!md)
- return 1;
- if (!md->hdr)
- mu_list_create(&md->hdr);
- mu_list_append(md->hdr, node);
- return 0;
-}
-
-
-/* Run-time execution */
-
-static char *
-ctx_getsym(void *data, char *str)
-{
- char *ret = smfi_getsymval(data, str);
- if (!ret) {
- struct message_data *md = priv_get(data);
- if (strcmp (str, "s") == 0)
- ret = md->helostr;
- }
- return ret;
-}
-
-static int
-ctx_setreply(void *data, char *code, char *xcode, char *message)
-{
- if (code) {
- if (!strchr(message, '\n'))
- return smfi_setreply(data, code, xcode, message);
- else {
- return sendmail_mlreply(data, code, xcode, message);
- }
- }
- return 0;
-}
-
-static void
-ctx_setheader(void *data, struct header_node *hdr)
-{
- priv_store_header_command(data, hdr);
-}
-
-
/* Logging & debugging */
int
@@ -409,801 +279,6 @@ host_in_relayed_domain_p(char *client)
}
-/* SMTP I/O functions */
-
-#define SMTP_MAJOR(c) ((c)/100)
-
-struct smtp_io_data {
- SMFICTX *ctx; /* Milter context */
- mu_stream_t stream; /* I/O stream */
- size_t send_off; /* Send offset */
- size_t recv_off; /* Receive offset */
- struct obstack stk; /* Obstack for keeping commands/replies */
- char *command; /* Last issued command */
- char *reply; /* Last received reply */
- char *start; /* First line of the reply, if it was multiline */
- char buf[128]; /* Input buffer */
- size_t level; /* Number of bytes in buf */
- int code; /* Reply code */
-};
-
-void
-transcript(struct smtp_io_data *io, char *prefix, const char *msg)
-{
- if (do_transcript) {
- int len = strlen(msg);
- if (msg[len-1] == '\n') {
- --len;
- if (len > 0 && msg[len-1] == '\r')
- --len;
- }
- if (len)
- logmsg(LOG_INFO, "%s%s %*.*s",
- mailfromd_msgid(io->ctx),
- prefix, len, len, msg);
- }
-}
-
-int
-smtp_io_data_init(struct smtp_io_data *dat, SMFICTX *ctx, mu_stream_t stream)
-{
- obstack_init(&dat->stk);
- dat->send_off = dat->recv_off = 0;
- dat->stream = stream;
- dat->start = dat->command = dat->reply = NULL;
- dat->level = 0;
- dat->ctx = ctx;
- if (ctx && priv_set_io(ctx, dat)) /* save the private data */
- return 1;
- return 0;
-}
-
-void
-smtp_io_data_destroy(struct smtp_io_data *dat)
-{
- if (dat) {
- mu_stream_close (dat->stream);
- mu_stream_destroy(&dat->stream,
- mu_stream_get_owner(dat->stream));
- obstack_free(&dat->stk, NULL);
- if (dat->ctx)
- priv_set_io(dat->ctx, NULL);
- }
-}
-
-int
-smtp_stream_wait(mu_stream_t stream, int flags, int *attempt)
-{
- int rc;
- int oflags = flags;
- struct timeval tv;
- while (*attempt < io_attempts) {
- tv.tv_sec = io_timeout;
- tv.tv_usec = 0;
- rc = mu_stream_wait(stream, &oflags, &tv);
- /* FIXME: smfi_progress */
- switch (rc) {
- case 0:
- if (flags & oflags)
- return 0;
- /* FALLTHROUGH */
- case EAGAIN:
- case EINPROGRESS:
- ++*attempt;
- continue;
-
- default:
- return rc;
- }
- }
-
- return ETIMEDOUT;
-}
-
-int
-smtp_wait(struct smtp_io_data *dat, int flags, int *attempt)
-{
- return smtp_stream_wait(dat->stream, flags, attempt);
-}
-
-int
-smtp_send(struct smtp_io_data *dat, char *command)
-{
- int attempt = 0;
- size_t len = strlen(command);
-
- dat->reply = NULL; /* Clear reply for logging purposes */
- transcript(dat, "SEND:", command);
- do {
- size_t nb;
- int rc = mu_stream_write(dat->stream, command, len,
- dat->send_off, &nb);
- if (rc == 0) {
- if (nb == 0) {
- mu_error("stream_write: wrote 0 bytes");
- return -1;
- }
- dat->send_off += nb;
- len -= nb;
- command += nb;
- } else if (rc == EAGAIN) {
- if (attempt < io_attempts) {
- rc = smtp_wait(dat, MU_STREAM_READY_WR,
- &attempt);
- if (rc) {
- mu_error ("smtp_wait failed: %s",
- mu_strerror(rc));
- return -1;
- }
- continue;
- } else {
- mu_error ("stream_write timed out");
- return -1;
- }
- } else {
- mu_error ("stream_write: %s", mu_strerror (rc));
- return -1;
- }
- } while (len > 0);
- return 0;
-}
-
-int
-smtp_send2(struct smtp_io_data *dat, char *command, char *arg)
-{
- obstack_grow(&dat->stk, command, strlen(command));
- if (arg)
- obstack_grow(&dat->stk, arg, strlen(arg));
- obstack_grow(&dat->stk, "\r\n", 2);
- obstack_1grow(&dat->stk, 0);
- dat->command = obstack_finish(&dat->stk);
-
- return smtp_send(dat, dat->command);
-}
-
-int
-smtp_send3(struct smtp_io_data *dat, char *command, char *arg1, char *arg2)
-{
- obstack_grow(&dat->stk, command, strlen(command));
- obstack_grow(&dat->stk, arg1, strlen(arg1));
- obstack_grow(&dat->stk, arg2, strlen(arg2));
- obstack_grow(&dat->stk, "\r\n", 2);
- obstack_1grow(&dat->stk, 0);
- dat->command = obstack_finish(&dat->stk);
-
- return smtp_send(dat, dat->command);
-}
-
-int
-smtp_recvline(struct smtp_io_data *dat)
-{
- int attempt = 0;
- for (;;) {
- char *p;
-
- if (dat->level == 0) {
- int rc = mu_stream_read(dat->stream,
- dat->buf, sizeof dat->buf,
- dat->recv_off, &dat->level);
- if (rc == 0) {
- if (dat->level == 0) {
- mu_error("stream_read: read 0 bytes");
- return -1;
- }
- dat->recv_off += dat->level;
- } else if (rc == EAGAIN) {
- if (attempt < io_attempts) {
- rc = smtp_wait(dat,
- MU_STREAM_READY_RD,
- &attempt);
- if (rc) {
- mu_error ("smtp_wait failed: %s",
- mu_strerror(rc));
- return -1;
- }
- continue;
- } else {
- mu_error("stream_read timed out");
- return -1;
- }
- } else {
- mu_error ("stream_read: %s", mu_strerror (rc));
- return -1;
- }
- }
- attempt = 0;
-
- p = memchr(dat->buf, '\n', dat->level);
- if (!p) {
- obstack_grow(&dat->stk, dat->buf, dat->level);
- dat->level = 0;
- continue;
- } else {
- size_t len = p - dat->buf + 1;
- obstack_grow(&dat->stk, dat->buf, len);
- obstack_1grow(&dat->stk, 0);
- dat->reply = obstack_finish(&dat->stk);
- dat->level -= len;
- memmove(dat->buf, dat->buf + len, dat->level);
- break;
- }
- }
- return 0;
-}
-
-int
-smtp_recv(struct smtp_io_data *dat)
-{
- char *p;
- dat->start = NULL;
- do {
- int code;
- int rc = smtp_recvline(dat);
- if (rc)
- return -1;
- transcript(dat, "RECV:", dat->reply);
- code = strtoul (dat->reply, &p, 0);
- if (p - dat->reply != 3 || (*p != '-' && *p != ' ')) {
- mu_error("Unexpected reply from server: %s",
- dat->reply);
- return -1;
- } else if (!dat->start) {
- dat->start = dat->reply;
- dat->code = code;
- } else if (dat->code != code) {
- mu_error("Unexpected reply code from server: %d",
- code);
- return -1;
- }
- } while (*p == '-');
- obstack_1grow (&dat->stk, 0);
- obstack_finish (&dat->stk);
- return 0;
-}
-
-const char *
-smtp_last_sent(struct smtp_io_data *dat)
-{
- if (dat->command) {
- size_t len = strcspn(dat->command, "\r\n");
- dat->command[len] = 0;
- return dat->command;
- }
- return "nothing";
-}
-
-const char *
-smtp_last_received(struct smtp_io_data *dat)
-{
- if (dat->reply) {
- size_t len = strcspn(dat->reply, "\r\n");
- dat->reply[len] = 0;
- return dat->reply;
- }
- return dat->reply ? dat->reply : "nothing";
-}
-
-
-
-/* Milter-specific functions */
-
-/* Verify whether EMAIL address is served by host CLIENT_ADDR. */
-mf_status
-check_on_host(eval_environ_t env, char *email, char *client_addr,
- char *ehlo, char *mailfrom)
-{
- int rc;
- mu_stream_t stream;
- struct smtp_io_data io;
- mf_status status = mf_success;
- int count = 0;
- SMFICTX *ctx = env_get_context(env);
-
- debug2(10, "email = %s, client_addr = %s", email, client_addr);
- rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, 25,
- source_address,
- MU_STREAM_NONBLOCK);
- if (rc) {
- mu_error("%scannot connect to `%s': %s",
- mailfromd_msgid(ctx), client_addr,
- mu_strerror (rc));
- return mf_temp_failure;
- }
-
- while ((rc = mu_stream_open(stream))) {
- if ((rc == EAGAIN || rc == EINPROGRESS)
- && count < io_attempts) {
- rc = smtp_stream_wait(stream, MU_STREAM_READY_WR,
- &count);
- if (rc == 0)
- continue;
- }
- mu_error("%sstream_open: %s, %d",
- mailfromd_msgid(ctx), mu_strerror(rc), count);
- mu_stream_destroy(&stream, mu_stream_get_owner(stream));
- return mf_temp_failure;
- }
- debug(100,"stream opened");
-
- if (smtp_io_data_init(&io, ctx, stream))
- status = mf_temp_failure;
- else {
- do {
- if (smtp_recv(&io)) {
- status = mf_temp_failure;
- break;
- } else if (SMTP_MAJOR(io.code) != 2) {
- status = SMTP_MAJOR(io.code) == 4 ?
- mf_temp_failure : mf_not_found;
- break;
- }
- smtp_send2(&io, "HELO ", ehlo);
- if (smtp_recv(&io)) {
- status = mf_temp_failure;
- break;
- } else if (SMTP_MAJOR(io.code) == 5) {
- /* Let's try EHLO, then */
- smtp_send2(&io, "EHLO ", ehlo);
- if (smtp_recv(&io)) {
- status = mf_not_found;
- break;
- }
- }
- if (SMTP_MAJOR(io.code) != 2) {
- status = SMTP_MAJOR(io.code) == 4 ?
- mf_temp_failure : mf_not_found;
- break;
- }
- smtp_send3(&io, "MAIL FROM: <", mailfrom, ">");
- if (smtp_recv(&io)) {
- status = mf_temp_failure;
- break;
- } else if (SMTP_MAJOR(io.code) != 2) {
- status = SMTP_MAJOR(io.code) == 4 ?
- mf_temp_failure : mf_not_found;
- break;
- }
- smtp_send3(&io, "RCPT TO: <", email, ">");
- if (smtp_recv(&io)) {
- status = mf_temp_failure;
- break;
- } else if (SMTP_MAJOR(io.code) != 2) {
- status = SMTP_MAJOR(io.code) == 4 ?
- mf_temp_failure : mf_not_found;
- break;
- }
- } while (0);
-
- set_last_poll_result(env,
- client_addr,
- smtp_last_sent(&io),
- smtp_last_received(&io));
-
- debug4(1,
- "%spoll exited with status: %s; sent \"%s\", got \"%s\"",
- mailfromd_msgid(ctx),
- mf_status_str(status),
- smtp_last_sent(&io),
- smtp_last_received(&io));
-
- smtp_send2(&io, "QUIT", NULL);
- smtp_io_data_destroy(&io);
- }
-
- return status;
-}
-
-mf_status
-check_mx_records(eval_environ_t env, char *email, char *client_addr,
- char *ehlo, char *mailfrom)
-{
- int i;
- mxbuf_t mxbuf;
- mf_status rc, mxstat = getmx(client_addr, mxbuf);
-
- switch (mxstat) {
- case mf_temp_failure:
- rc = mf_temp_failure;
- break;
-
- case mf_failure:
- case mf_not_found:
- rc = mf_not_found;
- break;
-
- case mf_success:
- debug1(2,"Checking MX servers for %s", email);
- rc = mf_not_found;
- for (i = 0; i < MAXMXCOUNT && mxbuf[i]; i++) {
- rc = check_on_host(env, email, mxbuf[i],
- ehlo, mailfrom);
- if (mf_resolved(rc))
- break;
- }
- freemx(mxbuf);
- break;
-
- default:
- abort();
- }
- return rc;
-}
-
-/* Method "strict". Verifies whether EMAIL is understood either by
- host CLIENT_ADDR or one of MX servers of its domain */
-mf_status
-method_strict(eval_environ_t env, char *email, char *client_addr,
- char *ehlo, char *mailfrom)
-{
- mf_status rc;
-
- if (email[0] == 0)
- return mf_success;
-
- rc = cache_get2(email, client_addr);
- if (!mf_resolved(rc)) {
- set_cache_used(env, 0);
- rc = check_on_host(env, email, client_addr, ehlo, mailfrom);
- if (!mf_resolved(rc)) {
- mf_status mx_stat;
- mx_stat = check_mx_records(env, email, client_addr,
- ehlo, mailfrom);
- if (mf_resolved(mx_stat)
- || mx_stat == mf_temp_failure)
- rc = mx_stat;
- }
- if (mf_resolved(rc))
- cache_insert2(email, client_addr, rc);
- } else {
- set_last_poll_result(env, client_addr, NULL, NULL);
- set_cache_used(env, 1);
- }
- return rc;
-}
-
-/* Method "standard". Verifies whether EMAIL is understood by
- any of its MXs */
-mf_status
-method_standard(eval_environ_t env, char *email, char *ehlo, char *mailfrom)
-{
- mf_status rc;
-
- if (email[0] == 0)
- return mf_success;
-
- rc = cache_get(email);
- if (!mf_resolved(rc)) {
- char *p = strchr(email, '@');
- set_cache_used(env, 0);
- if (p == NULL) {
- mu_error("Invalid address: %s", email);
- rc = mf_not_found;
- } else {
- rc = check_mx_records(env, email, p+1, ehlo, mailfrom);
- if (rc != mf_success) {
- mf_status host_stat;
- host_stat = check_on_host(env, email, p+1,
- ehlo, mailfrom);
- if (mf_resolved(host_stat)
- || host_stat == mf_temp_failure)
- rc = host_stat;
- }
- }
- if (mf_resolved(rc))
- cache_insert(email, rc);
- } else {
- set_last_poll_result(env, email, NULL, NULL);
- set_cache_used(env, 1);
- }
- return rc;
-}
-
-mf_status
-listens_on (const char *client_addr, int port)
-{
- unsigned count = 0;
- mu_stream_t stream;
- int rc;
-
- if (port == 0)
- port = 25;
-
- debug2(10, "client_addr = %s, port = %d", client_addr, port);
- rc = mu_tcp_stream_create_with_source_ip (&stream, client_addr, 25,
- source_address,
- MU_STREAM_NONBLOCK);
- if (rc) {
- debug1 (10, "mu_tcp_stream_create_with_source_ip: %s",
- mu_strerror (rc));
- return mf_failure;
- }
-
- while ((rc = mu_stream_open(stream))) {
- if ((rc == EAGAIN || rc == EINPROGRESS)
- && count < io_attempts) {
- rc = smtp_stream_wait(stream, MU_STREAM_READY_WR,
- &count);
- if (rc == 0)
- continue;
- }
- break;
- }
- mu_stream_destroy(&stream, mu_stream_get_owner(stream));
-
- debug3 (10, "mu_stream_open(%s): %s, %u", client_addr, mu_strerror(rc),
- count);
-
- return rc == 0 ? mf_success :
- (rc == EAGAIN || rc == EINPROGRESS) ?
- mf_temp_failure : mf_failure;
-}
-
-/* Cleanup functions */
-void
-filter_cleanup(SMFICTX *ctx)
-{
- struct message_data *md = priv_get(ctx);
- debug(100,"cleaning up");
- if (md) {
- free(md->helostr);
- destroy_environment(md->env);
- smtp_io_data_destroy(md->io);
- mu_list_destroy(&md->hdr);
- free(md);
- smfi_setpriv(ctx, NULL);
- }
-}
-
-
-/* Milter interface functions */
-
-int
-xeval(eval_environ_t env, enum smtp_state tag)
-{
- int rc;
-
- rc = eval_environment(env, entry_point[tag]);
- if (rc) {
- struct locus locus;
- const char *symbol = environment_get_null_symbol(env,
- &locus);
-
- mu_error("Execution of the configuration program was not finished");
- if (symbol)
- mu_error("%s:%lu: Symbol `%s' is not defined",
- locus.file,
- (unsigned long) locus.line,
- symbol);
- }
- return rc;
-}
-
-sfsistat
-mlfi_eval(SMFICTX *ctx, enum smtp_state tag)
-{
- int rc;
- sfsistat status;
- struct message_data *md = priv_get(ctx);
-
- rc = xeval(md->env, tag);
- if (rc == 0)
- status = environment_get_status(md->env);
- else {
- smfi_setreply(ctx, "410", NULL,
- "Local configuration error; please try again later");
- status = SMFIS_TEMPFAIL;
- }
- log_status(status, ctx);
- return status;
-}
-
-sfsistat
-mlfi_helo(SMFICTX *ctx, char *helohost)
-{
- sfsistat status;
- struct message_data *md = priv_get(ctx);
-
- debug1(70, "Processing xxfi_helo: %s", helohost);
- md->helostr = strdup(helohost);
- env_init(md->env);
- env_push_string(md->env, helohost);
- env_make_frame(md->env);
- status = mlfi_eval(ctx, smtp_state_helo);
- env_leave_frame(md->env, 1);
- return status;
-}
-
-sfsistat
-mlfi_envfrom(SMFICTX *ctx, char **argv)
-{
- sfsistat status;
- struct message_data *md = priv_get(ctx);
- debug2(70, "Processing xxfi_envfrom: %s%s", argv[0],
- argv[1] ? " (more)" : "");
- env_init(md->env);
- env_push_string(md->env, argv[0]);
- env_make_frame(md->env);
- status = mlfi_eval(ctx, smtp_state_envfrom);
- env_leave_frame(md->env, 1);
- return status;
-}
-
-sfsistat
-mlfi_envrcpt(SMFICTX *ctx, char ** argv)
-{
- sfsistat status;
- struct message_data *md = priv_get(ctx);
-
- debug3(70, "Processing xxfi_envrcpt: %s%s - %lu", argv[0],
- argv[1] ? " (more)" : "",
- get_rcpt_count(md->env));
- env_init(md->env);
- env_push_string(md->env, argv[0]);
- env_make_frame(md->env);
- incr_rcpt_count(md->env);
- status = mlfi_eval(ctx, smtp_state_envrcpt);
- env_leave_frame(md->env, 1);
- return status;
-}
-
-sfsistat
-mlfi_header(SMFICTX *ctx, char *headerf, char *headerv)
-{
- sfsistat status;
- struct message_data *md = priv_get(ctx);
-
- debug(10, "Processing xxfi_header:");
- env_init(md->env);
- env_push_string(md->env, headerv);
- env_push_string(md->env, headerf);
- env_make_frame(md->env);
- status = mlfi_eval(ctx, smtp_state_header);
- env_leave_frame(md->env, 2);
- return status;
-}
-
-sfsistat
-mlfi_eoh(SMFICTX *ctx)
-{
- sfsistat status;
- struct message_data *md = priv_get(ctx);
- debug(70, "Processing xxfi_eoh");
- env_init(md->env);
- env_make_frame(md->env);
- status = mlfi_eval(ctx, smtp_state_eoh);
- env_leave_frame(md->env, 0);
- return status;
-}
-
-sfsistat
-mlfi_body(SMFICTX *ctx, unsigned char * bodyp, size_t len)
-{
- sfsistat status;
- struct message_data *md = priv_get(ctx);
- debug1(70, "Processing xxfi_body: %lu", (unsigned long) len);
- env_init(md->env);
- env_push_number(md->env, len);
- env_push_string(md->env, bodyp);
- env_make_frame(md->env);
- status = mlfi_eval(ctx, smtp_state_body);
- env_leave_frame(md->env, 2);
- return status;
-}
-
-static int
-run_header_command(void *item, void *data)
-{
- struct header_node *hdr = item;
- SMFICTX *ctx = data;
-
- debug3(50,
- "%s %s: %s",
- header_command_str(hdr->opcode),
- hdr->name, hdr->value);
- switch (hdr->opcode) {
- case header_add:
- smfi_addheader(ctx, hdr->name, hdr->value);
- break;
-
- case header_replace:
- smfi_chgheader(ctx, hdr->name, 1, hdr->value);
- break;
-
- case header_delete:
- smfi_chgheader(ctx, hdr->name, 1, NULL);
- break;
- }
- return 0;
-}
-
-
-sfsistat
-mlfi_eom(SMFICTX *ctx)
-{
- sfsistat status;
- struct message_data *md = priv_get(ctx);
-
- debug(70, "Processing xxfi_eom");
-
- env_init(md->env);
- env_make_frame(md->env);
- status = mlfi_eval(ctx, smtp_state_body);
- env_leave_frame(md->env, 0);
- if ((status == SMFIS_ACCEPT || status == SMFIS_CONTINUE) && md->hdr) {
- debug(50,"executing header commands");
- mu_list_do(md->hdr, run_header_command, ctx);
- }
-
- clear_rcpt_count(md->env);
-
- return status;
-}
-
-sfsistat
-mlfi_abort(SMFICTX *ctx)
-{
- filter_cleanup(ctx);
- return SMFIS_CONTINUE; /* FIXME? */
-}
-
-sfsistat
-mlfi_close(SMFICTX *ctx)
-{
- filter_cleanup(ctx);
- return SMFIS_CONTINUE;
-}
-
-struct smfiDesc smfilter =
-{
- "MailfromFilter",
- SMFI_VERSION,
- SMFIF_ADDHDRS|SMFIF_CHGHDRS,
- NULL, /* connection info filter */
- NULL, /* SMTP HELO command filter */
- NULL, /* envelope sender filter */
- NULL, /* envelope recipient filter */
- NULL, /* header filter */
- NULL, /* end of header */
- NULL, /* body block filter */
- mlfi_eom, /* end of message */
- mlfi_abort, /* message aborted */
- mlfi_close, /* connection cleanup */
-};
-
-void
-milter_enable_state(enum smtp_state state)
-{
- switch (state) {
- case smtp_state_helo:
- smfilter.xxfi_helo = mlfi_helo;
- break;
-
- case smtp_state_envfrom:
- smfilter.xxfi_envfrom = mlfi_envfrom;
- break;
-
- case smtp_state_envrcpt:
- smfilter.xxfi_envrcpt = mlfi_envrcpt;
- break;
-
- case smtp_state_header:
- smfilter.xxfi_header = mlfi_header;
- break;
-
- case smtp_state_eoh:
- smfilter.xxfi_eoh = mlfi_eoh;
- break;
-
- case smtp_state_body:
- smfilter.xxfi_body = mlfi_body;
- break;
-
- default:
- break;
- }
-}
-
-
/* Option handling.
There are two classes of options: those that can be set using #pragma
@@ -2042,62 +1117,6 @@ static struct argp argp = {
/* Auxiliary functions */
-/* Check whether local socket P exists. Act in accordance with the settings
- of --remove command line option. */
-static void
-check_local_portspec(char *p)
-{
- struct stat st;
-
- if (stat(p, &st)) {
- if (errno == ENOENT)
- return; /* That's OK. The socket must not exist */
- mu_error("cannot stat file `%s': %s",
- p, mu_strerror(errno));
- exit(EX_SOFTWARE);
- } else if (!force_remove) {
- mu_error("File `%s' already exist. Remove it or use --remove option.", p);
- exit(EX_SOFTWARE);
- }
-
- if (unlink (p)) {
- mu_error("cannot unlink file `%s': %s", p, mu_strerror(errno));
- exit(EX_SOFTWARE);
- }
-}
-
-void
-check_portspec(char *portspec)
-{
- static struct spectab {
- char *proto;
- void (*check)(char *);
- } *sp, spectab[] = {
- { "unix", check_local_portspec },
- { "local", check_local_portspec },
- { "inet", NULL },
- { "inet6", NULL },
- };
-
- if (strchr(portspec, ':') == NULL) {
- mu_error("Missing protocol in port specification");
- exit(1);
- }
-
- for (sp = spectab; sp < spectab + sizeof(spectab)/sizeof(spectab[0]);
- sp++) {
- int len = strlen(sp->proto);
- if (strlen(portspec) > len+1
- && strncasecmp(portspec, sp->proto, len) == 0
- && portspec[len] == ':') {
- if (sp->check)
- sp->check(portspec + len + 1);
- return;
- }
- }
- mu_error("Unknown port specification: %s", portspec);
-}
-
/* Switch to the given UID/GID */
int
switch_to_privs(uid_t uid, gid_t gid)
@@ -2208,39 +1227,6 @@ switch_to_privs(uid_t uid, gid_t gid)
return rc;
}
-/* Check whether pidfile NAME exists and if so, whether its PID is still
- active. Exit if it is. */
-void
-check_pidfile(char *name)
-{
- unsigned long pid;
- FILE *fp = fopen(name, "r");
- if (!fp) {
- if (errno == ENOENT)
- return;
- mu_error("Cannot open pidfile `%s': %s",
- name, mu_strerror(errno));
- exit(EX_TEMPFAIL);
- }
- if (fscanf(fp, "%lu", &pid) != 1) {
- mu_error("Cannot get pid from pidfile `%s'", name);
- } else {
- if (kill(pid, 0) == 0) {
- mu_error("%s appears to run with pid %lu. If it does not, remove `%s' and retry.",
- program_invocation_short_name,
- pid,
- name);
- exit(EX_USAGE);
- }
- }
- fclose(fp);
- if (unlink(pidfile)) {
- mu_error("Cannot unlink pidfile `%s'",
- name, mu_strerror(errno));
- exit(EX_USAGE);
- }
-}
-
static char *license =
" This is mailfromd filter.\n"
" Copyright (C) 2005, 2006 Sergey Poznyakoff\n"
@@ -2259,7 +1245,7 @@ static char *license =
" with this program; if not, write to the Free Software Foundation,\n"
" Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n";
-static void
+void
priv_setup()
{
if (getuid() == 0) {
@@ -2279,48 +1265,6 @@ priv_setup()
}
void
-mailfromd_daemon()
-{
- int rc;
-
- priv_setup();
-
- if (!foreground)
- check_pidfile(pidfile);
-
- check_portspec(portspec);
-
- if (smfi_setconn(portspec) == MI_FAILURE) {
- mu_error("smfi_setconn: %s", mu_strerror(errno));
- exit(EX_SOFTWARE);
- }
-
- if (smfi_register(smfilter) == MI_FAILURE) {
- mu_error("smfi_register failed");
- exit(EX_UNAVAILABLE);
- }
-
- if (!foreground) {
- if (daemon(0, 0) == -1) {
- mu_error("cannot become a daemon: %s",
- mu_strerror(errno));
- exit(EX_OSERR);
- }
- umask(0117);
- mu_daemon_create_pidfile(pidfile);
- rc = smfi_main();
- mu_error("OK. REMOVING PIDFILE");
- mu_daemon_remove_pidfile();
- } else {
- umask(0117);
- rc = smfi_main();
- mu_error("smfi_main failed: rc=%d errno=%s",
- rc, strerror (errno));
- }
- exit(rc);
-}
-
-void
assert_db_format()
{
if (!format_option) {

Return to:

Send suggestions and report system problems to the System administrator.