diff options
-rw-r--r-- | driver.c | 48 | ||||
-rw-r--r-- | fetchmail.c | 110 | ||||
-rw-r--r-- | fetchmail.h | 6 |
3 files changed, 29 insertions, 135 deletions
@@ -298,7 +298,7 @@ struct query *ctl; /* query control record */ { char buf [MSGBUFSIZE+1]; char *bufp, *headers, *fromhdr,*tohdr,*cchdr,*bcchdr,*received_for,*envto; - int n, oldlen, mboxfd; + int n, oldlen; int inheaders,lines,sizeticker; FILE *sinkfp; RETSIGTYPE (*sigchld)(); @@ -497,23 +497,26 @@ struct query *ctl; /* query control record */ /* time to address the message */ if (ctl->mda[0]) /* we have a declared MDA */ { - int i, nlocals = 0; - char **sargv, **sp; + int length = 0; + char *names, *cmd; /* * We go through this in order to be able to handle very * long lists of users and (re)implement %s. */ for (idp = xmit_names; idp; idp = idp->next) - nlocals++; - sp = sargv = (char **)alloca(sizeof(char **) * ctl->mda_argcount+nlocals+2); - for (i = 0; i < ctl->mda_argcount; i++) - if (strcmp("%s", ctl->mda_argv[i])) - *sp++ = ctl->mda_argv[i]; - else - for (idp = xmit_names; idp; idp = idp->next) - *sp++ = idp->id; - *sp = (char *)NULL; + length += (strlen(idp->id) + 1); + names = (char *)alloca(length); + names[0] = '\0'; + for (idp = xmit_names; idp; idp = idp->next) + { + strcat(names, idp->id); + strcat(names, " "); + } + cmd = (char *)alloca(strlen(ctl->mda) + length); + sprintf(cmd, ctl->mda, names); + if (outlevel == O_VERBOSE) + error(0, 0, "about to deliver with: %s", cmd); #ifdef HAVE_SETEUID /* @@ -525,14 +528,14 @@ struct query *ctl; /* query control record */ seteuid(ctl->uid); #endif /* HAVE_SETEUID */ - mboxfd = openmailpipe(sargv); + sinkfp = popen(cmd, "w"); #ifdef HAVE_SETEUID /* this will fail quietly if we didn't start as root */ seteuid(0); #endif /* HAVE_SETEUID */ - if (mboxfd < 0) + if (!sinkfp) { error(0, 0, "MDA open failed"); return(PS_IOERR); @@ -620,7 +623,7 @@ struct query *ctl; /* query control record */ /* write all the headers */ if (ctl->mda[0]) - n = write(mboxfd,headers,oldlen); + n = fwrite(headers, 1, oldlen, sinkfp); else if (sinkfp) n = SockWrite(headers, oldlen, sinkfp); @@ -631,7 +634,7 @@ struct query *ctl; /* query control record */ error(0, errno, "writing RFC822 headers"); if (ctl->mda[0]) { - closemailpipe(mboxfd); + pclose(sinkfp); signal(SIGCHLD, sigchld); } return(PS_IOERR); @@ -684,7 +687,7 @@ struct query *ctl; /* query control record */ strcat(errmsg, "\n"); if (ctl->mda[0]) - write(mboxfd, errmsg, strlen(errmsg)); + fputs(errmsg, sinkfp); else if (sinkfp) SockWrite(errmsg, strlen(errmsg), sinkfp); } @@ -708,7 +711,7 @@ struct query *ctl; /* query control record */ /* ship out the text line */ if (ctl->mda[0]) - n = write(mboxfd,bufp,strlen(bufp)); + n = fwrite(bufp, 1, strlen(bufp), sinkfp); else if (sinkfp) n = SockWrite(bufp, strlen(bufp), sinkfp); @@ -719,7 +722,7 @@ struct query *ctl; /* query control record */ error(0, errno, "writing message text"); if (ctl->mda[0]) { - closemailpipe(mboxfd); + pclose(sinkfp); signal(SIGCHLD, sigchld); } return(PS_IOERR); @@ -736,11 +739,14 @@ struct query *ctl; /* query control record */ int rc; /* close the delivery pipe, we'll reopen before next message */ - rc = closemailpipe(mboxfd); + rc = pclose(sinkfp); signal(SIGCHLD, sigchld); if (rc) + { + error(0, 0, "MDA exited abnormally or returned nonzero status"); return(PS_IOERR); - } + } + } else if (sinkfp) { /* write message terminator */ diff --git a/fetchmail.c b/fetchmail.c index 59b59a01..d8f42e51 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -587,28 +587,6 @@ static int load_params(int argc, char **argv, int optind) ctl->servernames->id); exit(PS_SYNTAX); } - - /* expand MDA commands */ - if (!check_only && ctl->mda[0]) - { - char *argp; - - /* punch nulls into the delimiting whitespace in the args */ - for (argp = ctl->mda, ctl->mda_argcount = 1; *argp != '\0'; ctl->mda_argcount++) - { - ctl->mda_argv[ctl->mda_argcount] = argp; - while (!(*argp == '\0' || isspace(*argp))) - argp++; - if (*argp != '\0') - *(argp++) = '\0'; - } - - ctl->mda_argv[ctl->mda_argcount] = (char *)NULL; - - ctl->mda_argv[0] = ctl->mda_argv[1]; - if ((argp = strrchr(ctl->mda_argv[1], '/')) != (char *)NULL) - ctl->mda_argv[1] = argp + 1 ; - } } } @@ -782,18 +760,9 @@ void dump_params (struct query *ctl) else if (outlevel == O_VERBOSE) printf(" No message size limit\n"); if (ctl->mda[0]) - { - char **cp; - - printf(" Messages will be delivered with %s, args:", - visbuf(ctl->mda_argv[0])); - for (cp = ctl->mda_argv+1; *cp; cp++) - printf(" %s", visbuf(*cp)); - putchar('\n'); - } + printf(" Messages will be delivered with '%s.'\n", visbuf(ctl->mda)); else - printf(" Messages will be SMTP-forwarded to '%s'.\n", - visbuf(ctl->smtphost)); + printf(" Messages will be SMTP-forwarded to '%s'.\n", visbuf(ctl->smtphost)); if (!ctl->localnames) printf(" No localnames declared for this host.\n"); else @@ -840,81 +809,6 @@ void dump_params (struct query *ctl) } } -int openmailpipe (char **argv) -/* open a one-way pipe to a mail delivery agent */ -{ - int pipefd [2]; - int childpid; - - if (outlevel == O_VERBOSE) - { - char **cp; - - printf("fetchmail: about to deliver via MDA %s, args:", - visbuf(argv[0])); - for (cp = argv+1; *cp; cp++) - printf(" %s", visbuf(*cp)); - putchar('\n'); - } - - if (pipe(pipefd) < 0) { - error(0, errno, "openmailpipe: pipe"); - return(-1); - } - if ((childpid = fork()) < 0) { - error(0, errno, "openmailpipe: fork"); - return(-1); - } - else if (childpid == 0) { - - /* in child process space */ - close(pipefd[1]); /* close the 'write' end of the pipe */ - close(0); /* get rid of inherited stdin */ - if (dup(pipefd[0]) != 0) { - error(0, errno, "openmailpipe: dup"); - _exit(1); - } - - execv(argv[0], argv + 1); - - /* if we got here, an error occurred */ - error(0, errno, "openmailpipe: exec"); - _exit(PS_SYNTAX); - - } - - /* in the parent process space */ - close(pipefd[0]); /* close the 'read' end of the pipe */ - return(pipefd[1]); -} - -int closemailpipe (fd) -/* close the pipe to the mail delivery agent */ -int fd; -{ - int err, status; - int childpid; - - if ((err = close(fd)) != 0) - error(0, errno, "closemailpipe: close"); - - childpid = wait(&status); - -#if defined(WIFEXITED) && defined(WEXITSTATUS) - /* - * Try to pass up an error if the MDA returned nonzero status, - * on the assumption that this means it was reporting failure. - */ - if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) - { - error(0, errno, "MDA exited abnormally or returned nonzero status"); - err = -1; - } -#endif - - return(err); -} - /* helper functions for string interpretation and display */ #define CTRL(x) ((x) & 0x1f) diff --git a/fetchmail.h b/fetchmail.h index e2d65be6..36282fff 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -78,10 +78,6 @@ struct query char smtphost[HOSTLEN+1]; char mda [MDALEN+1]; - /* per-user MDA arguments */ - int mda_argcount; - char *mda_argv[MDA_MAXARGS]; - /* per-user control flags */ int keep; int fetchall; @@ -199,8 +195,6 @@ struct query *hostalloc(struct query *); int parsecmdline (int, char **, struct query *); void optmerge(struct query *, struct query *); char *MD5Digest (char *); -int openmailpipe (char **); -int closemailpipe(int); int daemonize(const char *, void (*)(int)); int prc_parse_file(const char *); |