X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=sink.c;h=5d92556f01d5435ef1d9e1d847521a4b50d6b350;hb=da989f7b8294e342572ec5f27f1a6f3f2b1fe56f;hp=703bea58fd7dca57308409a9b537356f920f4237;hpb=6827f405d1239ba41e62181c88ab6cff51ca44f8;p=~andy%2Ffetchmail diff --git a/sink.c b/sink.c index 703bea58..5d92556f 100644 --- a/sink.c +++ b/sink.c @@ -65,7 +65,7 @@ void smtp_close(struct query *ctl, int sayquit) batchcount = 0; } -void smtp_rset(struct query *ctl) +static void smtp_rset(struct query *ctl) /* reset the mail transaction */ { if (SMTP_rset(ctl->smtp_socket, ctl->smtphostmode) == SM_UNRECOVERABLE) @@ -76,7 +76,7 @@ void smtp_rset(struct query *ctl) } } -int smtp_open(struct query *ctl) +int smtp_setup(struct query *ctl) /* try to open a socket to the appropriate SMTP server for this query */ { /* maybe it's time to close the socket in order to force delivery */ @@ -114,7 +114,7 @@ int smtp_open(struct query *ctl) */ struct idlist *idp; const char *id_me = run.invisible ? ctl->server.truename : fetchmailhost; - int oldphase = phase; + int oldphase; char *parsed_host = NULL; errno = 0; @@ -131,7 +131,7 @@ int smtp_open(struct query *ctl) for (idp = ctl->smtphunt; idp; idp = idp->next) { char *cp; - char *portnum = SMTP_PORT; + const char *portnum = SMTP_PORT; ctl->smtphost = idp->id; /* remember last host tried. */ if (ctl->smtphost[0]=='/') @@ -262,12 +262,13 @@ char *rcpt_address(struct query *ctl, const char *id, } static int send_bouncemail(struct query *ctl, struct msgblk *msg, - int userclass, char *message /* should have \r\n at the end */, + int userclass, const char *message /* should have \r\n at the end */, int nerrors, char *errors[]) /* bounce back an error report a la RFC 1892 */ { char daemon_name[15 + HOSTLEN] = "MAILER-DAEMON@"; - char boundary[BUFSIZ], *bounce_to; + char boundary[BUFSIZ]; + const char *bounce_to; int sock; static char *fqdn_of_host = NULL; const char *md1 = "MAILER-DAEMON", *md2 = "MAILER-DAEMON@"; @@ -440,8 +441,6 @@ 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); @@ -465,15 +464,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 @@ -648,6 +639,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". */ @@ -784,7 +778,7 @@ static int open_bsmtp_sink(struct query *ctl, struct msgblk *msg, if (fflush(sinkfp) || ferror(sinkfp)) { - report(stderr, GT_("BSMTP preamble write failed.\n")); + report(stderr, GT_("BSMTP preamble write failed: %s.\n"), strerror(errno)); return(PS_BSMTP); } @@ -1129,9 +1123,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' */ @@ -1235,7 +1229,10 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, * under all BSDs and Linux) */ orig_uid = getuid(); - seteuid(ctl->uid); + if (seteuid(ctl->uid)) { + 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"); @@ -1244,7 +1241,10 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, #ifdef HAVE_SETEUID /* this will fail quietly if we didn't start as root */ - seteuid(orig_uid); + 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) @@ -1269,6 +1269,8 @@ int open_sink(struct query *ctl, struct msgblk *msg, { *bad_addresses = *good_addresses = 0; + if (want_progress() && outlevel >= O_VERBOSE && !ctl->mda && !ctl->bsmtp) puts(""); + if (ctl->bsmtp) /* dump to a BSMTP batch file */ return(open_bsmtp_sink(ctl, msg, good_addresses, bad_addresses)); /* @@ -1276,7 +1278,7 @@ int open_sink(struct query *ctl, struct msgblk *msg, * open a socket fails, fall through to attempt delivery via * local MDA. */ - else if (!ctl->mda && smtp_open(ctl) != -1) + else if (!ctl->mda && smtp_setup(ctl) != -1) return(open_smtp_sink(ctl, msg, good_addresses, bad_addresses)); /* @@ -1347,8 +1349,31 @@ int close_sink(struct query *ctl, struct msgblk *msg, flag forward) /* perform end-of-message actions on the current output sink */ { int smtp_err; - if (ctl->mda) - { + + if (want_progress() && outlevel >= O_VERBOSE && !ctl->mda && !ctl->bsmtp) puts(""); + + if (ctl->bsmtp && sinkfp) { + int error, oerrno; + + /* implicit disk-full check here... */ + fputs(".\r\n", sinkfp); + error = ferror(sinkfp); + oerrno = errno; + if (strcmp(ctl->bsmtp, "-")) + { + if (fclose(sinkfp) == EOF) { + error = 1; + oerrno = errno; + } + sinkfp = (FILE *)NULL; + } + if (error) + { + report(stderr, + GT_("Message termination or close of BSMTP file failed: %s\n"), strerror(oerrno)); + return(FALSE); + } + } else if (ctl->mda) { int rc = 0, e = 0, e2 = 0, err = 0; /* close the delivery pipe, we'll reopen before next message */ @@ -1364,8 +1389,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 */ @@ -1388,25 +1411,6 @@ int close_sink(struct query *ctl, struct msgblk *msg, flag forward) return(FALSE); } } - else if (ctl->bsmtp && sinkfp) - { - int error; - - /* implicit disk-full check here... */ - fputs(".\r\n", sinkfp); - error = ferror(sinkfp); - if (strcmp(ctl->bsmtp, "-")) - { - if (fclose(sinkfp) == EOF) error = 1; - sinkfp = (FILE *)NULL; - } - if (error) - { - report(stderr, - GT_("Message termination or close of BSMTP file failed\n")); - return(FALSE); - } - } else if (forward) { /* write message terminator */