summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@users.sourceforge.net>2009-06-27 09:36:22 +0100
committerJosé Fonseca <jfonseca@users.sourceforge.net>2009-06-27 09:36:22 +0100
commitfb1e6a8b4126365c72d70c92f954755a2f4fbf87 (patch)
tree16c280f9f8d9d5d30507d9fbff024b1c7c0ce6b1
parent0a0e366a973ae0d57d74c82d3ca420c624794d38 (diff)
Force mail to be delivered by the MDA.
SF patch 2489938.
-rw-r--r--NEWS2
-rw-r--r--esmtprc.515
-rw-r--r--lexer.l1
-rw-r--r--local.c88
-rw-r--r--local.h1
-rw-r--r--main.c9
-rw-r--r--parser.y3
7 files changed, 86 insertions, 33 deletions
diff --git a/NEWS b/NEWS
index a5dd2b6..ac99852 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ News
* Development:
+ * Option to force local only MDA (Robert A.M. Diamond).
+
* Use locking in esmtp-wrapper (Phil Sutter).
* Update mutt option name in the user manual (Wu Fengguang).
diff --git a/esmtprc.5 b/esmtprc.5
index b0bcbd9..415ce0e 100644
--- a/esmtprc.5
+++ b/esmtprc.5
@@ -149,6 +149,21 @@ place an %F.
Some common MDAs are "/usr/bin/procmail -d %T", "/usr/bin/deliver" and
"/usr/lib/mail.local %T".
+.TP
+\fBforce_mda\fR
+Force mail to be delivered by the MDA.
+
+When set, any mail from anywhere to anywhere will instead be delivered to the
+value of force_mda. It will also only be delivered locally, via the mda. This
+will let you have a very minimal mail set-up, which can ONLY handle local mail.
+
+For example:
+
+.nf
+ mda = "procmail -d %T"
+ force_mda = "\fIsomeuser\fR"
+.fi
+
.SH SEE ALSO
esmtp(1)
diff --git a/lexer.l b/lexer.l
index 668837f..6996a3a 100644
--- a/lexer.l
+++ b/lexer.l
@@ -69,6 +69,7 @@ reverse_path { return REVERSE_PATH; }
sender { return SENDER; }
message_id { return MSGID; }
mda { return MDA; }
+force_mda { return FORCE_MDA; }
= { return MAP; }
diff --git a/local.c b/local.c
index 494d163..e4afa29 100644
--- a/local.c
+++ b/local.c
@@ -17,13 +17,26 @@
char *mda = NULL;
+char *force_mda = NULL;
FILE *mda_fp = NULL;
int local_address(const char *address)
{
- return !strchr(address, '@');
+ if (!force_mda)
+ {
+ /* TODO:
+ *
+ * A litle more searching
+ * Does the regex"[^@]*\@(.*)" resolve to 127.0.0.1 or a local ip?
+ *
+ * Maybe it should be delivered locally?
+ */
+ return !strchr(address, '@');
+ }
+
+ return 1;
}
/** replace ' by _ */
@@ -58,40 +71,54 @@ void local_init(message_t *message)
/* get user addresses for %T */
if (strstr(before, "%T"))
{
- struct list_head *ptr;
- char *p;
-
- /*
- * We go through this in order to be able to handle very
- * long lists of users and (re)implement %s.
- */
- nameslen = 0;
- list_for_each(ptr, &message->local_recipients)
+ if (!force_mda)
{
- recipient_t *recipient = list_entry(ptr, recipient_t, list);
-
- assert(recipient->address);
-
- nameslen += (strlen(recipient->address) + 3); /* string + quotes + ' ' */
- }
-
- names = (char *)xmalloc(nameslen + 1); /* account for '\0' */
- p = names;
- list_for_each(ptr, &message->local_recipients)
- {
- recipient_t *recipient = list_entry(ptr, recipient_t, list);
- int written;
-
- sanitize(recipient->address);
- written = sprintf(p, "'%s' ", recipient->address);
- if (written < 0)
+ struct list_head *ptr;
+ char *p;
+
+ /*
+ * We go through this in order to be able to handle very
+ * long lists of users and (re)implement %s.
+ */
+ nameslen = 0;
+ list_for_each(ptr, &message->local_recipients)
+ {
+ recipient_t *recipient = list_entry(ptr, recipient_t, list);
+
+ assert(recipient->address);
+
+ nameslen += (strlen(recipient->address) + 3); /* string + quotes + ' ' */
+ }
+
+ names = (char *)xmalloc(nameslen + 1); /* account for '\0' */
+ p = names;
+ list_for_each(ptr, &message->local_recipients)
+ {
+ recipient_t *recipient = list_entry(ptr, recipient_t, list);
+ int written;
+
+ sanitize(recipient->address);
+ written = sprintf(p, "'%s' ", recipient->address);
+ if (written < 0)
+ {
+ perror(NULL);
+ exit(EX_OSERR);
+ }
+ p += written;
+ }
+ names[--nameslen] = '\0'; /* chop trailing space */
+ } else {
+ nameslen = (strlen(force_mda) + 3); // 'force_mda'
+ names = (char *)xmalloc(nameslen + 1); // 'force_mda'\0
+
+ // Let's skip sanitization?
+ // Hope the config isn't evil to us 0.o
+ if (sprintf(names, "'%s' ", force_mda) < 0)
{
perror(NULL);
exit(EX_OSERR);
}
- p += written;
}
- names[--nameslen] = '\0'; /* chop trailing space */
}
/* get From address for %F */
@@ -216,4 +243,7 @@ void local_cleanup(void)
if(mda)
free(mda);
+
+ if(force_mda)
+ free(force_mda);
}
diff --git a/local.h b/local.h
index 726364a..f2cd0f1 100644
--- a/local.h
+++ b/local.h
@@ -12,6 +12,7 @@
extern char *mda;
+extern char *force_mda;
extern FILE *mda_fp;
diff --git a/main.c b/main.c
index 3023673..87d16ad 100644
--- a/main.c
+++ b/main.c
@@ -371,15 +371,18 @@ int main (int argc, char **argv)
exit (EX_USAGE);
}
+ /* Parse the rc file.
+ *
+ * Do this before message_add_recipient; to enable the force_mda recipient
+ */
+ rcfile_parse(rcfile);
+
/* Add remaining program arguments as message recipients. */
while (optind < argc)
message_add_recipient(message, argv[optind++]);
identities_init();
- /* Parse the rc file. */
- rcfile_parse(rcfile);
-
drop_sgids();
message_send(message);
diff --git a/parser.y b/parser.y
index bc01fb7..b2c7a8f 100644
--- a/parser.y
+++ b/parser.y
@@ -64,7 +64,7 @@ void yyerror (const char *s);
char *sval;
}
-%token IDENTITY DEFAULT HOSTNAME USERNAME PASSWORD STARTTLS CERTIFICATE_PASSPHRASE PRECONNECT POSTCONNECT MDA QUALIFYDOMAIN HELO FORCE SENDER MSGID REVERSE_PATH
+%token IDENTITY DEFAULT HOSTNAME USERNAME PASSWORD STARTTLS CERTIFICATE_PASSPHRASE PRECONNECT POSTCONNECT MDA QUALIFYDOMAIN HELO FORCE SENDER MSGID REVERSE_PATH FORCE_MDA
%token MAP
@@ -119,6 +119,7 @@ statement : HOSTNAME map STRING { identity->host = xstrdup($3); SET_DEFAULT_IDEN
| MSGID map DISABLED { identity->prohibit_msgid = 1; SET_DEFAULT_IDENTITY; }
| MSGID map ENABLED { identity->prohibit_msgid = 0; SET_DEFAULT_IDENTITY; }
| MDA map STRING { mda = xstrdup($3); }
+ | FORCE_MDA map STRING { force_mda = xstrdup($3); }
| DEFAULT { default_identity = identity; }
;