diff -Naur fetchmail-5.9.14.orig/sink.c fetchmail-5.9.14/sink.c --- fetchmail-5.9.14.orig/sink.c Mon Sep 9 16:44:05 2002 +++ fetchmail-5.9.14/sink.c Mon Sep 9 16:46:43 2002 @@ -216,6 +216,37 @@ *cp = '_'; } +static char *rcpt_address(struct query *ctl, const char *id, + int usesmtpname) +{ + static char addr[HOSTLEN+USERNAMELEN+1]; + if (strchr(id, '@')) + { +#ifdef HAVE_SNPRINTF + snprintf(addr, sizeof (addr), "%s", id); +#else + sprintf(addr, "%s", id); +#endif /* HAVE_SNPRINTF */ + } + else if (usesmtpname && ctl->smtpname) + { +#ifdef HAVE_SNPRINTF + snprintf(addr, sizeof (addr), "%s", ctl->smtpname); +#else + sprintf(addr, "%s", ctl->smtpname); +#endif /* HAVE_SNPRINTF */ + } + else + { +#ifdef HAVE_SNPRINTF + snprintf(addr, sizeof (addr), "%s(_at_)%s", id, ctl->destaddr); +#else + sprintf(addr, "%s(_at_)%s", id, ctl->destaddr); +#endif /* HAVE_SNPRINTF */ + } + return addr; +} + static int send_bouncemail(struct query *ctl, struct msgblk *msg, int userclass, char *message, int nerrors, char *errors[]) @@ -306,8 +337,8 @@ char *error; /* Minimum RFC1894 compliance + Diagnostic-Code field */ SockPrintf(sock, "\r\n"); - SockPrintf(sock, "Final-Recipient: rfc822; %s(_at_)%s\r\n", - idp->id, fetchmailhost); + SockPrintf(sock, "Final-Recipient: rfc822; %s\r\n", + rcpt_address (ctl, idp->id, 1)); SockPrintf(sock, "Last-Attempt-Date: %s\r\n", rfc822timestamp()); SockPrintf(sock, "Action: failed\r\n"); @@ -358,6 +389,10 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg) /* handle SMTP errors based on the content of SMTP_response */ /* return of PS_REFUSED deletes mail from the server; PS_TRANSIENT keeps it */ +/* Don't call this to handle response to RCPT TO: address; + * RSET discards the message body and it doesn't get sent to the + * valid recipients. + */ { int smtperr = atoi(smtp_response); char *responses[1]; @@ -365,17 +400,9 @@ xalloca(responses[0], char *, strlen(smtp_response)+1); strcpy(responses[0], 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->smtp_socket); /* 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 @@ -458,7 +485,7 @@ #ifdef __DONT_FEED_THE_SPAMMERS__ if (run.bouncemail) send_bouncemail(ctl, msg, XMIT_ACCEPT, - "Invalid address in MAIL FROM/RCPT TO (SMTP error 553).\r\n", + "Invalid address in MAIL FROM (SMTP error 553).\r\n", 1, responses); #endif /* __DONT_FEED_THE_SPAMMERS__ */ return(PS_REFUSED); @@ -647,14 +674,8 @@ for (idp = msg->recipients; idp; idp = idp->next) if (idp->val.status.mark == XMIT_ACCEPT) { - if (ctl->smtpname) - fprintf(sinkfp, "RCPT TO: %s\r\n", ctl->smtpname); - else if (strchr(idp->id, '@')) - fprintf(sinkfp, - "RCPT TO: %s\r\n", idp->id); - else - fprintf(sinkfp, - "RCPT TO: %s(_at_)%s\r\n", idp->id, ctl->destaddr); + fprintf(sinkfp, "RCPT TO: %s\r\n", + rcpt_address (ctl, idp->id, 1)); *good_addresses = 0; } @@ -827,10 +848,7 @@ if (SMTP_from(ctl->smtp_socket, ap, options) != SM_OK) { - int err = handle_smtp_report(ctl, msg); - - SMTP_rset(ctl->smtp_socket); /* stay on the safe side */ - return(err); + return(handle_smtp_report(ctl, msg)); } /* @@ -845,25 +863,9 @@ for (idp = msg->recipients; idp; idp = idp->next) if (idp->val.status.mark == XMIT_ACCEPT) { - if (strchr(idp->id, '@')) - strcpy(addr, idp->id); - else { - if (ctl->smtpname) { -#ifdef HAVE_SNPRINTF - snprintf(addr, sizeof(addr), "%s", ctl->smtpname); -#else - sprintf(addr, "%s", ctl->smtpname); -#endif /* HAVE_SNPRINTF */ - - } else { -#ifdef HAVE_SNPRINTF - snprintf(addr, sizeof(addr), "%s(_at_)%s", idp->id, ctl->destaddr); -#else - sprintf(addr, "%s(_at_)%s", idp->id, ctl->destaddr); -#endif /* HAVE_SNPRINTF */ - } - } - if (SMTP_rcpt(ctl->smtp_socket, addr) == SM_OK) + const char *address; + address = rcpt_address (ctl, idp->id, 1); + if (SMTP_rcpt(ctl->smtp_socket, address) == SM_OK) (*good_addresses)++; else { @@ -886,14 +888,14 @@ if (outlevel >= O_VERBOSE) report(stderr, GT_("%cMTP listener doesn't like recipient address `%s'\n"), - ctl->listener, addr); + ctl->listener, address); break; case PS_REFUSED: if (outlevel >= O_VERBOSE) report(stderr, GT_("%cMTP listener doesn't really like recipient address `%s'\n"), - ctl->listener, addr); + ctl->listener, address); break; } } @@ -934,18 +936,8 @@ SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ return(PS_REFUSED); } - if (strchr(run.postmaster, '@')) - strncpy(addr, run.postmaster, sizeof(addr)); - else - { -#ifdef HAVE_SNPRINTF - snprintf(addr, sizeof(addr), "%s(_at_)%s", run.postmaster, ctl->destaddr); -#else - sprintf(addr, "%s(_at_)%s", run.postmaster, ctl->destaddr); -#endif /* HAVE_SNPRINTF */ - } - - if (SMTP_rcpt(ctl->smtp_socket, addr) != SM_OK) + if (SMTP_rcpt(ctl->smtp_socket, + rcpt_address (ctl, run.postmaster, 0)) != SM_OK) { report(stderr, GT_("can't even send to %s!\n"), run.postmaster); SMTP_rset(ctl->smtp_socket); /* required by RFC1870 */ @@ -962,7 +954,6 @@ */ if (SMTP_data(ctl->smtp_socket) != SM_OK) { - SMTP_rset(ctl->smtp_socket); /* stay on the safe side */ return(handle_smtp_report(ctl, msg)); } @@ -1277,13 +1268,11 @@ { if (handle_smtp_report(ctl, msg) != PS_REFUSED) { - SMTP_rset(ctl->smtp_socket); /* stay on the safe side */ return(FALSE); } else { report(stderr, GT_("SMTP listener refused delivery\n")); - SMTP_rset(ctl->smtp_socket); /* stay on the safe side */ return(TRUE); } }