diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1996-10-29 01:54:58 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1996-10-29 01:54:58 +0000 |
commit | 800186e3873690997bdbd7e1b60c83ca2d9819cd (patch) | |
tree | f15eaa7f138442747b0ed3691a70b817619a0b32 | |
parent | 83840832840c57e9ae6109627a1e18e0c6b04d58 (diff) | |
download | fetchmail-800186e3873690997bdbd7e1b60c83ca2d9819cd.tar.gz fetchmail-800186e3873690997bdbd7e1b60c83ca2d9819cd.tar.bz2 fetchmail-800186e3873690997bdbd7e1b60c83ca2d9819cd.zip |
Only open one conneection per host in daemon mode.
svn path=/trunk/; revision=414
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | driver.c | 60 | ||||
-rw-r--r-- | fetchmail.c | 38 | ||||
-rw-r--r-- | fetchmail.h | 6 |
4 files changed, 68 insertions, 37 deletions
@@ -2,6 +2,7 @@ pl 1.9.4 (): * Correct status interpretation in closemailpipe() (thanks to Neil Harkins). +* Tweak SMTP forwarding to only open one listener per SMTP host in daemon mode. pl 1.9.3 (Sun Oct 27 22:35:33 EST 1996): * Handle nested parens in RFC822 comments. @@ -49,7 +49,6 @@ char tag[TAGLEN]; static int tagnum; #define GENSYM (sprintf(tag, "a%04d", ++tagnum), tag) -static int mboxfd; /* desc to which retrieved message will be written */ static char *shroud; /* string to shroud in debug output, if non-NULL */ static int strcrlf(dst, src, count) @@ -449,29 +448,26 @@ struct idlist **xmit_names; /* list of recipient names parsed out */ } #endif /* HAVE_GETHOSTBYNAME */ -int smtp_open(host) -/* try to open a socket to given host's SMTP server */ -char *host; +static int smtp_open(ctl) +/* try to open a socket to the appropriate SMTP server for this query */ +struct query *ctl; { - if ((mboxfd = Socket(host, SMTP_PORT)) < 0 - || SMTP_ok(mboxfd, NULL) != SM_OK - || SMTP_helo(mboxfd, "localhost") != SM_OK) - { - close(mboxfd); - mboxfd = -1; - } - - return(mboxfd); -} + ctl = ctl->leader; /* go to the SMTP leader for this query */ -void smtp_close() -/* close the current SMTP connection */ -{ - if (mboxfd != -1) + /* if no socket to this host is already set up, try to open one */ + if (ctl->smtp_socket == -1) { - SMTP_quit(mboxfd); - close(mboxfd); + if ((ctl->smtp_socket = Socket(ctl->smtphost, SMTP_PORT)) == -1) + return(-1); + else if (SMTP_ok(ctl->smtp_socket, NULL) != SM_OK + || SMTP_helo(ctl->smtp_socket, ctl->servername) != SM_OK) + { + close(ctl->smtp_socket); + ctl->smtp_socket = -1; + } } + + return(ctl->smtp_socket); } static int gen_readmsg (socket, len, delimited, ctl) @@ -483,7 +479,7 @@ struct query *ctl; /* query control record */ { char buf [MSGBUFSIZE+1]; char *bufp, *headers, *fromhdr, *tohdr, *cchdr, *bcchdr; - int n, oldlen; + int n, oldlen, mboxfd; int inheaders,lines,sizeticker; /* read the message content from the server */ @@ -643,7 +639,7 @@ struct query *ctl; /* query control record */ } else { - if (ctl->mda[0] == '\0' && (smtp_open(ctl->smtphost) < 0)) + if (ctl->mda[0] == '\0' && ((mboxfd = smtp_open(ctl)) < 0)) { free_uid_list(&xmit_names); fprintf(stderr, "fetchmail: SMTP connect failed\n"); @@ -826,7 +822,6 @@ const struct method *proto; /* protocol method table */ tagnum = 0; tag[0] = '\0'; /* nuke any tag hanging out from previous query */ ok = 0; - mboxfd = -1; if (setjmp(restart) == 1) fprintf(stderr, @@ -946,14 +941,6 @@ const struct method *proto; /* protocol method table */ fputc(' ', stderr); } - /* - * If we're forwarding via SMTP, mboxfd is initialized - * at this point (it was set at start of retrieval). - * If we're using an MDA it's not set -- gen_readmsg() - * may have to parse message headers to know what - * delivery addresses should be passed to the MDA - */ - /* read the message and ship it to the output sink */ ok = gen_readmsg(socket, len, @@ -1029,11 +1016,18 @@ const struct method *proto; /* protocol method table */ signal(SIGALRM, sigsave); closeUp: - if (!ctl->mda[0]) - smtp_close(); return(ok); } +void smtp_close(mboxfd) +/* close the current SMTP connection */ +int mboxfd; +{ + if (mboxfd != -1) + { + close(mboxfd); + } +} #if defined(HAVE_STDARG_H) void gen_send(int socket, char *fmt, ... ) /* assemble command in printf(3) style and send to the server */ diff --git a/fetchmail.c b/fetchmail.c index d6b8349d..5f76b8c2 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -63,7 +63,6 @@ char *user; /* the name of the invoking user */ static void termhook(); static char *lockfile; static int popstatus; -static struct query *ctl; RETSIGTYPE donothing(sig) int sig; {signal(sig, donothing);} @@ -72,7 +71,7 @@ int argc; char **argv; { int st, lossage, bkgd = FALSE; - struct query def_opts; + struct query def_opts, *ctl, *mp; int parsestatus, implicitmode; char *home, *tmpdir, tmpbuf[BUFSIZ]; struct passwd *pw; @@ -175,6 +174,7 @@ char **argv; /* merge in wired defaults, do sanity checks and prepare internal fields */ for (ctl = querylist; ctl; ctl = ctl->next) + { if (ctl->active && !(implicitmode && ctl->skip)) { #ifdef HAVE_GETHOSTBYNAME @@ -232,6 +232,30 @@ char **argv; } #endif /* HAVE_GETHOSTBYNAME */ + /* + * Assign SMTP leaders. We want to allow all query blocks + * sharing the same SMTP host to use the same SMTP connection. + * To accomplish this, we initialize each query block's leader + * field to point to the first block in the list with a matching + * SMTP host. + * + * In the typical case, there will be only one SMTP host (the + * client machine) and thus just one SMTP leader (and one listener + * process) through the entire run. + */ + if (!ctl->mda[0]) + { + for (mp = querylist; mp && mp != ctl; mp = mp->next) + if (strcmp(mp->smtphost, ctl->smtphost) == 0) + { + ctl->leader = mp->leader; + goto no_new_leader; + } + ctl->leader = ctl; + ctl->smtp_socket = -1; + no_new_leader:; + } + /* sanity checks */ if (ctl->port < 0) { @@ -263,6 +287,9 @@ char **argv; ctl->mda_argv[1] = argp + 1 ; } } + } + + /* set up to do lock protocol */ if ((tmpdir = getenv("TMPDIR")) == (char *)NULL) @@ -499,9 +526,16 @@ char **argv; void termhook(int sig) /* to be executed on normal or signal-induced termination */ { + struct query *ctl; + if (sig != 0) fprintf(stderr, "terminated with signal %d\n", sig); + /* terminate all SMTP connections cleanly */ + for (ctl = querylist; ctl; ctl = ctl->next) + if (ctl->leader == ctl && ctl->smtp_socket != -1) + SMTP_quit(ctl->smtp_socket); + if (!check_only) write_saved_lists(querylist, idfile); diff --git a/fetchmail.h b/fetchmail.h index b03899d0..4022f625 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -92,9 +92,11 @@ struct query /* internal use */ int active; - struct query *next; /* next host in chain */ + struct query *next; /* next query control block in chain */ + struct query *leader; /* pointer to this query's SMTP leader */ + int smtp_socket; /* socket descriptor for SMTP connection */ unsigned int uid; /* UID of user to deliver to */ - char digest [DIGESTLEN]; + char digest [DIGESTLEN]; /* md5 digest buffer */ #ifdef HAVE_GETHOSTBYNAME char *canonical_name; /* DNS canonical name of server host */ #endif /* HAVE_GETHOSTBYNAME */ |