X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=sink.c;h=5e9bef9864eb80f6ae3bac880a33b582be8a1e55;hb=f16d8d23439b5569f0c2e1af22494708b507f277;hp=76cd2bb5abfb7bb94809933495b03e8149ad15c6;hpb=82d02e1f39249cce1362c0a41c4fe2a7005ae835;p=~andy%2Ffetchmail diff --git a/sink.c b/sink.c index 76cd2bb5..5e9bef98 100644 --- a/sink.c +++ b/sink.c @@ -15,20 +15,9 @@ #include #include #include -#ifdef HAVE_MEMORY_H -#include -#endif /* HAVE_MEMORY_H */ -#if defined(STDC_HEADERS) #include -#endif -#if defined(HAVE_UNISTD_H) #include -#endif -#if defined(HAVE_STDARG_H) #include -#else -#include -#endif #include #include @@ -42,7 +31,7 @@ #include "socket.h" #include "smtp.h" -#include "i18n.h" +#include "gettext.h" /* BSD portability hack...I know, this is an ugly place to put it */ #if !defined(SIGCHLD) && defined(SIGCLD) @@ -441,23 +430,9 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg) { int smtperr = atoi(smtp_response); char *responses[1]; - struct idlist *walk; - int found = 0; responses[0] = xstrdup(smtp_response); -#ifdef __UNUSED__ - /* - * Don't do this! It can really mess you up if, for example, you're - * reporting an error with a single RCPT TO address among several; - * RSET discards the message body and it doesn't get sent to the - * valid recipients. - */ - smtp_rset(ctl); /* stay on the safe side */ - if (outlevel >= O_DEBUG) - report(stdout, GT_("Saved error is still %d\n"), smtperr); -#endif /* __UNUSED */ - /* * Note: send_bouncemail message strings are not made subject * to gettext translation because (a) they're going to be @@ -466,15 +441,7 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg) * messages, which are probably in English (none of the * MTAs I know about are internationalized). */ - for( walk = ctl->antispam; walk; walk = walk->next ) - if ( walk->val.status.num == smtperr ) - { - found=1; - break; - } - - /* if (str_find(&ctl->antispam, smtperr)) */ - if ( found ) + if (str_find(&ctl->antispam, smtperr)) { /* * SMTP listener explicitly refuses to deliver mail @@ -542,12 +509,6 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg) * (b) we wouldn't want spammers to get confirmation that * this address is live, anyway. */ -#ifdef __DONT_FEED_THE_SPAMMERS__ - if (run.bouncemail) - send_bouncemail(ctl, msg, XMIT_ACCEPT, - "Invalid address in MAIL FROM (SMTP error 553).\r\n", - 1, responses); -#endif /* __DONT_FEED_THE_SPAMMERS__ */ free(responses[0]); return(PS_REFUSED); @@ -626,10 +587,7 @@ static int handle_smtp_report_without_bounce(struct query *ctl, struct msgblk *m return(PS_REFUSED); case 553: /* invalid sending domain */ -#ifdef __DONT_FEED_THE_SPAMMERS__ - if (run.bouncemail) - return(PS_SUCCESS); -#endif /* __DONT_FEED_THE_SPAMMERS__ */ + /* do not send bounce mail - it would feed spammers */ return(PS_REFUSED); default: @@ -649,6 +607,9 @@ int stuffline(struct query *ctl, char *buf) int n, oldphase; char *last; + if (!buf) + return -1; + /* The line may contain NUL characters. Find the last char to use * -- the real line termination is the sequence "\n\0". */ @@ -1103,9 +1064,7 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, int *good_addresses, int *bad_addresses) /* open a stream to a local MDA */ { -#ifdef HAVE_SETEUID uid_t orig_uid; -#endif /* HAVE_SETEUID */ struct idlist *idp; int length = 0, fromlen = 0, nameslen = 0; char *names = NULL, *before, *after, *from = NULL; @@ -1130,9 +1089,9 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, */ nameslen = 0; for (idp = msg->recipients; idp; idp = idp->next) - if ((idp->val.status.mark == XMIT_ACCEPT)) + if (idp->val.status.mark == XMIT_ACCEPT) nameslen += (strlen(idp->id) + 1); /* string + ' ' */ - if ((*good_addresses == 0)) + if (*good_addresses == 0) nameslen = strlen(run.postmaster); names = (char *)xmalloc(nameslen + 1); /* account for '\0' */ @@ -1191,6 +1150,16 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, for (dp = after, sp = before; (*dp = *sp); dp++, sp++) { if (sp[0] != '%') continue; + if (sp > before && sp[-1] == '\'') { + report(stderr, GT_("MDA option contains single-quoted %%%c expansion.\n"), sp[1]); + report(stderr, GT_("Refusing to deliver. Check the manual and fix your mda option.\n")); + free(before); + free(after); + if (from) free(from); + if (names) free(names); + return PS_SYNTAX; + } + /* need to expand? BTW, no here overflow, because in ** the worst case (end of string) sp[1] == '\0' */ if (sp[1] == 's' || sp[1] == 'T') { @@ -1228,7 +1197,6 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, if (outlevel >= O_DEBUG) report(stdout, GT_("about to deliver with: %s\n"), before); -#ifdef HAVE_SETEUID /* * Arrange to run with user's permissions if we're root. * This will initialize the ownership of any files the @@ -1240,19 +1208,16 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, report(stderr, GT_("Cannot switch effective user id to %ld: %s\n"), (long)ctl->uid, strerror(errno)); return PS_IOERR; } -#endif /* HAVE_SETEUID */ sinkfp = popen(before, "w"); free(before); before = NULL; -#ifdef HAVE_SETEUID /* this will fail quietly if we didn't start as root */ if (seteuid(orig_uid)) { report(stderr, GT_("Cannot switch effective user id back to original %ld: %s\n"), (long)orig_uid, strerror(errno)); return PS_IOERR; } -#endif /* HAVE_SETEUID */ if (!sinkfp) { @@ -1396,8 +1361,6 @@ int close_sink(struct query *ctl, struct msgblk *msg, flag forward) e = errno; sinkfp = (FILE *)NULL; } - else - rc = e = 0; deal_with_sigchld(); /* Restore SIGCHLD handling to reap zombies */ @@ -1585,15 +1548,7 @@ int open_warning_by_mail(struct query *ctl) /* if rfc2047charset is non-NULL, encode the line (that is assumed to be * a header line) as per RFC-2047 using rfc2047charset as the character * set field */ -#if defined(HAVE_STDARG_H) void stuff_warning(const char *rfc2047charset, struct query *ctl, const char *fmt, ... ) -#else -void stuff_warning(rfc2047charset, ctl, fmt, va_alist) -const char *charset; -struct query *ctl; -const char *fmt; /* printf-style format */ -va_dcl -#endif { /* make huge -- i18n can bulk up error messages a lot */ char buf[2*MSGBUFSIZE+4]; @@ -1605,11 +1560,7 @@ va_dcl * case it was a string constant. We make a virtue of that necessity * here by supporting stdargs/varargs. */ -#if defined(HAVE_STDARG_H) va_start(ap, fmt) ; -#else - va_start(ap); -#endif vsnprintf(buf, sizeof(buf) - 2, fmt, ap); va_end(ap); @@ -1630,4 +1581,18 @@ void close_warning_by_mail(struct query *ctl, struct msgblk *msg) close_sink(ctl, msg, TRUE); } +void abort_message_sink(struct query *ctl) +/* + * Forcibly close the SMTP connection and re-open. + * + * Used to abort message delivery once the DATA command has been issued. + * Required because all text after the DATA command is considered to be + * part of the message body (it is impossible to issue an SMTP command + * to abort message delivery once the DATA command has been issued). + */ +{ + smtp_close(ctl, 0); + smtp_setup(ctl); +} + /* sink.c ends here */