aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--design-notes.html44
-rw-r--r--driver.c36
-rw-r--r--fetchmail.c6
-rw-r--r--fetchmail.h1
-rw-r--r--fetchmail.man15
-rw-r--r--options.c27
-rw-r--r--rcfile_l.l1
-rw-r--r--rcfile_y.y7
-rw-r--r--sample.rcfile1
10 files changed, 108 insertions, 32 deletions
diff --git a/NEWS b/NEWS
index 3d44c352..dd19ec46 100644
--- a/NEWS
+++ b/NEWS
@@ -8,7 +8,6 @@
* Allow -c -F to work to flush messages without retrieval.
* Read from /etc/fetchmailrc before ~/.fetchmailrc?
* Do is_host_alias checks by comparing IP addresses rather than names?
-* Make the antispam response configurable.
* Handle multi-homed hosts correctly.
Release Notes:
@@ -23,6 +22,7 @@ fetchmail-4.4.0 ():
* Ron Kaminsky <kam@Orbotech.Co.IL> sent a patch to RFC1730-encode passwords
sent to IMAP servers. This allows them to contain doublequotes and
backslashes.
+* Made the antispam response configurable.
There are 269 people on fetchmail-friends and 144 on fetchmail-announce.
diff --git a/design-notes.html b/design-notes.html
index 54549ff8..b6ddec2d 100644
--- a/design-notes.html
+++ b/design-notes.html
@@ -10,7 +10,7 @@
<table width="100%" cellpadding=0><tr>
<td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
<td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 1998/03/04 05:45:27 $
+<td width="30%" align=right>$Date: 1998/03/06 04:17:44 $
</table>
<HR>
<H1 ALIGN=CENTER>Design Notes On Fetchmail</H1>
@@ -287,6 +287,46 @@ in a system's libc, but we can just include that source file if the
day comes when we want to support IPv6 without the inet6-apps
library. It just makes life easier.<P>
+<H1>Checklist for Adding Options
+
+Adding a control option is not complicated in principle, but there are
+a lot of fiddly details in the process. You'll need to do the
+following minimum steps.
+
+<UL>
+<LI>Add a field to represent the control in <code>struct query</code> or
+ <code>struct hostdata</code>.
+
+<LI>Pick a token to declare the option in the .fetchmailrc file. Add
+ the token to <code>rcfile_l</code>.
+
+<LI>Go to <code>rcfile_y.y</code>. Add the token to the grammar. Don't
+ forget the <code>%token</code> declaration. Add proper
+ <code>FLAG_FORCE</code> and <code>FLAG_MERGE</code> actions.
+
+<LI>Pick a long-form option name, and a one-letter short option if any
+ are left. Go to <code>options.c</code>. Pick a new <code>LA_<code>
+ value. Hack the <code>longoptions</code> table to set up the
+ association. Hack the big switch statement to set the option.
+ Hack the `?' message to describe it.
+
+<LI>If the default is nonzero, set it in <code>def_opts</code> near the top of
+ <code>load_params</code> in <code>fetchmail.c</code>.
+
+<LI>Add code to dump the option value in <code>fetchmail.c:dump_params</code>.
+
+<LI>Document the option in fetchmail.man. This will require at least
+ two changes; one to the collected table of options, and one full
+ text description of the option.
+
+<LI>Add the new token and a brief description to the header comment of
+ sample.rcfile.
+
+<LI>Add an entry to NEWS.
+</UL>
+
+There may be other things you have to do in the way of logic, of course.<P>
+
<H1>Lessons learned</H1>
<H3>1. Server-side state is essential</H3>
@@ -423,7 +463,7 @@ all shaped the design in one way or another.<P>
<table width="100%" cellpadding=0><tr>
<td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
<td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 1998/03/04 05:45:27 $
+<td width="30%" align=right>$Date: 1998/03/06 04:17:44 $
</table>
<P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com">&lt;esr@snark.thyrsus.com&gt;</A></ADDRESS>
diff --git a/driver.c b/driver.c
index 6575373e..22896547 100644
--- a/driver.c
+++ b/driver.c
@@ -1232,30 +1232,34 @@ int num; /* index of message */
{
int smtperr = atoi(smtp_response);
+ if (smtperr == ctl->antispam)
+ {
+ /*
+ * SMTP listener explicitly refuses to deliver mail
+ * coming from this address, probably due to an
+ * anti-spam domain exclusion. Respect this. Don't
+ * try to ship the message, and don't prevent it from
+ * being deleted. Typical values.
+ *
+ * 571 = sendmail's "unsolicited email refused"
+ * 501 = exim's old antispam response
+ * 550 = exim's new antispam response (temporary)
+ */
+ free(headers);
+ free_str_list(&xmit_names);
+ return(PS_REFUSED);
+ }
+
/*
* Suppress error message only if the response specifically
- * means `excluded for policy reasons'. We *should* see
+ * meant `excluded for policy reasons'. We *should* see
* an error when the return code is less specific.
*/
- if (smtperr >= 400 && smtperr != 571)
+ if (smtperr >= 400)
error(0, -1, "SMTP error: %s", smtp_response);
switch (smtperr)
{
- case 571: /* sendmail's "unsolicited email refused" */
- case 501: /* exim's old antispam response */
- case 550: /* exim's new antispam response (temporary) */
- /*
- * SMTP listener explicitly refuses to deliver
- * mail coming from this address, probably due
- * to an anti-spam domain exclusion. Respect
- * this. Don't try to ship the message, and
- * don't prevent it from being deleted.
- */
- free(headers);
- free_str_list(&xmit_names);
- return(PS_REFUSED);
-
case 452: /* insufficient system storage */
/*
* Temporary out-of-queue-space condition on the
diff --git a/fetchmail.c b/fetchmail.c
index 316cd3c5..0f187c68 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -655,6 +655,7 @@ static int load_params(int argc, char **argv, int optind)
memset(&def_opts, '\0', sizeof(struct query));
def_opts.smtp_socket = -1;
def_opts.smtpaddress = (char *)0;
+ def_opts.antispam = 571;
def_opts.server.protocol = P_AUTO;
def_opts.server.timeout = CLIENT_TIMEOUT;
@@ -1107,6 +1108,11 @@ void dump_params (struct query *ctl)
printf(" Host part of MAIL FROM line will be %s\n",
ctl->smtpaddress);
}
+ if (ctl->antispam != -1)
+ printf(" Listener SMTP reponse %d will be treated as a spam block\n",
+ ctl->antispam);
+ else if (outlevel == O_VERBOSE)
+ printf(" Spam-blocking disabled\n");
if (ctl->preconnect)
printf(" Server connection will be brought up with '%s.'\n",
visbuf(ctl->preconnect));
diff --git a/fetchmail.h b/fetchmail.h
index e4c51f4e..a4cccde0 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -144,6 +144,7 @@ struct query
struct idlist *smtphunt; /* list of SMTP hosts to try forwarding to */
char *smtphost; /* actual SMTP host to point to */
char *smtpaddress; /* address we want to force in the delivery messages */
+ int antispam; /* listener's antispam response */
char *mda; /* local MDA to pass mail to */
char *preconnect; /* pre-connection command to execute */
char *postconnect; /* post-connection command to execute */
diff --git a/fetchmail.man b/fetchmail.man
index deded9db..50c947fd 100644
--- a/fetchmail.man
+++ b/fetchmail.man
@@ -217,6 +217,12 @@ Specify the domain to be put in RCPT TO lines shipped to SMTP. The
name of the SMTP server (as specified by --smtphost, or defaulted to
"localhost") is used when this is not specified.
.TP
+.B \-Z nnn, --antispam nnn
+(Keyword: antispam)
+Specifies the numeric SMTP error that is to be interpreted as a
+spam-block response from the listener. A value of -1 disables
+this option.
+.TP
.B \-m, \--mda
(Keyword: mda)
You can force mail to be passed to an MDA directly (rather than
@@ -719,7 +725,8 @@ move to 550 soon.
.PP
The
.I fetchmail
-code recognizes any of these error codes and discards the message. This is the
+code recognizes and discards the message on a code that defaults to
+sendmail's 571 but can be set with the `antispam' option. This is the
.I only
circumstance under which fetchmail ever discards mail.
.P
@@ -866,6 +873,12 @@ T}
smtphost -S T{
Specify smtp host(s) to forward to
T}
+smtpaddress -D T{
+Specify the domain to be put in RCPT TO lines
+T}
+antispam -Z T{
+Specify what SMTP return is interpreted as a spam-policy block
+T}
mda -m T{
Specify MDA for local delivery
T}
diff --git a/options.c b/options.c
index b16d0041..f104c1a2 100644
--- a/options.c
+++ b/options.c
@@ -46,14 +46,15 @@
#define LA_FOLDER 28
#define LA_SMTPHOST 29
#define LA_SMTPADDR 30
-#define LA_BATCHLIMIT 31
-#define LA_FETCHLIMIT 32
-#define LA_EXPUNGE 33
-#define LA_MDA 34
-#define LA_NETSEC 35
-#define LA_INTERFACE 36
-#define LA_MONITOR 37
-#define LA_YYDEBUG 38
+#define LA_ANTISPAM 31
+#define LA_BATCHLIMIT 32
+#define LA_FETCHLIMIT 33
+#define LA_EXPUNGE 34
+#define LA_MDA 35
+#define LA_NETSEC 36
+#define LA_INTERFACE 37
+#define LA_MONITOR 38
+#define LA_YYDEBUG 39
/* options still left: CgGhHjJoORUwWxXYzZ */
static const char *shortoptions =
@@ -97,6 +98,7 @@ static const struct option longoptions[] = {
{"folder", required_argument, (int *) 0, LA_FOLDER },
{"smtphost", required_argument, (int *) 0, LA_SMTPHOST },
{"smtpaddress", required_argument, (int *) 0, LA_SMTPADDR },
+ {"antispam", required_argument, (int *) 0, LA_ANTISPAM },
{"batchlimit",required_argument, (int *) 0, LA_BATCHLIMIT },
{"fetchlimit",required_argument, (int *) 0, LA_FETCHLIMIT },
@@ -326,8 +328,12 @@ struct query *ctl; /* option record to be initialized */
break;
case 'D':
case LA_SMTPADDR:
- ctl->smtpaddress = xstrdup(optarg);
- break;
+ ctl->smtpaddress = xstrdup(optarg);
+ break;
+ case 'Z':
+ case LA_ANTISPAM:
+ c = atoi(optarg);
+ ctl->antispam = NUM_VALUE(c);
case 'b':
case LA_BATCHLIMIT:
c = atoi(optarg);
@@ -434,6 +440,7 @@ struct query *ctl; /* option record to be initialized */
#endif /* NET_SECURITY */
fputs(" -S, --smtphost set SMTP forwarding host\n", stderr);
fputs(" -D, --smtpaddress set SMTP delivery domain to use\n", stderr);
+ fputs(" -Z, --antispam, set antispam response value\n", stderr);
fputs(" -b, --batchlimit set batch limit for SMTP connections\n", stderr);
fputs(" -B, --fetchlimit set fetch limit for server connections\n", stderr);
fputs(" -e, --expunge set max deletions between expunges\n", stderr);
diff --git a/rcfile_l.l b/rcfile_l.l
index c55f7180..995ebfc1 100644
--- a/rcfile_l.l
+++ b/rcfile_l.l
@@ -51,6 +51,7 @@ pass(word)? { return PASSWORD; }
folder(s)? { return FOLDER; }
smtp(host)? { return SMTPHOST; }
smtpaddress { return SMTPADDRESS; }
+antispam { return SPAMRESPONSE; }
mda { return MDA; }
pre(connect)? { return PRECONNECT; }
post(connect)? { return POSTCONNECT; }
diff --git a/rcfile_y.y b/rcfile_y.y
index 110e8081..68d61c7e 100644
--- a/rcfile_y.y
+++ b/rcfile_y.y
@@ -64,7 +64,7 @@ extern char * yytext;
%token DEFAULTS POLL SKIP VIA AKA LOCALDOMAINS PROTOCOL
%token AUTHENTICATE TIMEOUT KPOP KERBEROS4 KERBEROS5 KERBEROS
%token ENVELOPE QVIRTUAL USERNAME PASSWORD FOLDER SMTPHOST MDA SMTPADDRESS
-%token PRECONNECT POSTCONNECT LIMIT
+%token SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT
%token IS HERE THERE TO MAP WILDCARD
%token BATCHLIMIT FETCHLIMIT EXPUNGE
%token SET LOGFILE DAEMON SYSLOG INVISIBLE NETSEC INTERFACE MONITOR
@@ -270,6 +270,7 @@ user_option : TO localnames HERE
| FOLDER folder_list
| SMTPHOST smtp_list
| SMTPADDRESS STRING {current.smtpaddress = xstrdup($2);}
+ | SPAMRESPONSE NUMBER {current.antispam = $2;}
| MDA STRING {current.mda = xstrdup($2);}
| PRECONNECT STRING {current.preconnect = xstrdup($2);}
| POSTCONNECT STRING {current.postconnect = xstrdup($2);}
@@ -486,7 +487,8 @@ static void record_current(void)
if (cmd_opts.smtphunt)
current.smtphunt = cmd_opts.smtphunt;
FLAG_FORCE(mda);
- FLAG_FORCE(smtpaddress);
+ FLAG_FORCE(smtpaddress);
+ FLAG_FORCE(antispam);
FLAG_FORCE(preconnect);
FLAG_FORCE(postconnect);
@@ -547,6 +549,7 @@ void optmerge(struct query *h2, struct query *h1)
FLAG_MERGE(password);
FLAG_MERGE(mda);
FLAG_MERGE(smtpaddress);
+ FLAG_MERGE(antispam);
FLAG_MERGE(preconnect);
FLAG_MERGE(keep);
diff --git a/sample.rcfile b/sample.rcfile
index facb95c3..da6a967e 100644
--- a/sample.rcfile
+++ b/sample.rcfile
@@ -45,6 +45,7 @@
# password (or pass) -- must be followed by a password string
# smtphost (or smtp) -- must be followed by host names
# smtpaddress -- must be followed by a host name
+# antispam -- must be followed by a numeric response value
# mda -- must be followed by an MDA command string
# preconnect (or pre) -- must be followed by an executable command
# postconnect (or post) -- must be followed by an executable command