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 */  | 
