diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2006-10-27 07:04:15 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2006-10-27 07:04:15 +0000 |
commit | 7ff7cd229dc9a481eea012329bafcc9d676b352b (patch) | |
tree | ef98a1ed54194f9cd44c526e60d9aa552a9d443b /src/main.c | |
parent | c7835aa508b47cbfdb2ae4f952176c92714bfd71 (diff) | |
download | mailfromd-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.c | 1058 |
1 files changed, 1 insertions, 1057 deletions
@@ -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(×tamp, &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) { |