Index: ChangeLog
===================================================================
RCS file: /home/mea/src/CVSROOT/zmailer/ChangeLog,v
retrieving revision 1.187
retrieving revision 1.189
diff -u -r1.187 -r1.189
--- ChangeLog 1999/07/05 11:08:00 1.187
+++ ChangeLog 1999/07/05 14:26:05 1.189
@@ -1,5 +1,16 @@
1999-07-05 Matti Aarnio <
[email protected]>
+ * transports/smtp/smtp.c:
+ Reworked the EHLO/HELO reconnect mechanisms. Now it
+ reconnects to the *same* address where EHLO failed
+ just previously. Otherwise it could connect to some
+ other address in case the target has several addresses..
+
+ * lib/rfc822scan.c:
+ MKERROR() did crash for some reason in previous form.
+ Modified call a bit and changed it into a static function
+ of its own. Now it seems to work.
+
* Makefile.in:
Version 2.99.51-pre1
Index: lib/rfc822scan.c
===================================================================
RCS file: /home/mea/src/CVSROOT/zmailer/lib/rfc822scan.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- lib/rfc822scan.c 1999/07/04 00:57:21 1.9
+++ lib/rfc822scan.c 1999/07/05 13:42:09 1.10
@@ -126,10 +126,23 @@
}
}
-#define MKERROR(msg,prev) tn = makeToken((msg), strlen(msg)); \
+#if 0
+#define MKERROR(msg,prevp) tn = makeToken((msg), strlen(msg)); \
tn->t_type = Error; \
- tn->t_next = (prev); \
- (prev) = tn;
+ tn->t_next = *(prevp); \
+ *(prevp) = tn;
+#else
+static void
+MKERROR(msg, prevp)
+ const char *msg;
+ token822 **prevp;
+{
+ token822 *tn = makeToken((msg), strlen(msg));
+ tn->t_type = Error;
+ tn->t_next = *(prevp);
+ *(prevp) = tn;
+}
+#endif
/*
* Recognize a compound token, or rather, a token which is defined by
@@ -167,12 +180,13 @@
} else if (*cp == cstart) {
if (type == Comment)
++nest;
- else
- MKERROR("illegal char in compound", *tlist);
+ else {
+ MKERROR("illegal char in compound", tlist);
+ }
} else if (*cp == '\\') {
if (n == 1) {
MKERROR("missing character after backslash",
- *tlist);
+ tlist);
/* Continue with next line, if existing! */
n = 0;
break;
@@ -182,7 +196,7 @@
++len;
} else if (*cp == '\r') {
/* type = Error; */
- MKERROR("illegal CR in token",*tlist);
+ MKERROR("illegal CR in token", tlist);
}
}
/* we either found cend, or ran off the end, either may be within
@@ -201,7 +215,7 @@
}
/* type = Error; */ /* hey, no reason to refuse a message */
sprintf(msgbuf, "missing closing '%c' in token", cend);
- MKERROR(msgbuf,*tlist);
+ MKERROR(msgbuf, tlist);
tp->t_pname = 0; /* ugly way of signalling scanner */
} else if (*cp == cend) { /* we found matching terminator */
++len; /* move past terminator */
@@ -308,19 +322,19 @@
continue;
if (n == 0 || !(rfc_ctype[(*cp) & 0xFF] & _l)) {
strcpy(msgbuf, "CR without LF (newline)");
- MKERROR(msgbuf,tlist);
+ MKERROR(msgbuf, &tlist);
} else if (n > 1 && (rfc_ctype[(*cp) & 0xFF] & _l)) {
while (--n > 0 && (rfc_ctype[(*++cp) & 0xFF] & _l))
continue;
strcpy(msgbuf,"too many newlines (LFs) in field[1]");
- MKERROR(msgbuf,tlist);
+ MKERROR(msgbuf, &tlist);
}
t.t_type = Fold;
} else if (ct & _l) { /* >= 1 LFs without CR is a fold too */
while (--n > 0 && (rfc_ctype[(*++cp) & 0xFF] & _l))
continue;
strcpy(msgbuf,"too many newlines (LFs) in field[2]");
- MKERROR(msgbuf,tlist);
+ MKERROR(msgbuf, &tlist);
t.t_type = Fold;
} else if ((ct & _s) && (*cp=='(' || *cp=='"' || *cp=='[')) {
TokenType type;
@@ -387,7 +401,7 @@
strcpy(msgbuf, "illegal control character");
if (t.t_len > n+1)
strcat(msgbuf, "s");
- MKERROR(msgbuf,tlist);
+ MKERROR(msgbuf, &tlist);
t.t_type = Atom;
}
t.t_len -= n;
@@ -407,6 +421,7 @@
}
} while (n > 0);
+ /* Reverse the token822 chain */
tp = tn = NULL;
for (tp = NULL; tlist != NULL; tlist = tn) {
tn = tlist->t_next;
Index: transports/smtp/smtp.c
===================================================================
RCS file: /home/mea/src/CVSROOT/zmailer/transports/smtp/smtp.c,v
retrieving revision 1.83
retrieving revision 1.87
diff -u -r1.83 -r1.87
--- transports/smtp/smtp.c 1999/07/04 14:13:13 1.83
+++ transports/smtp/smtp.c 1999/07/05 15:45:53 1.87
@@ -322,6 +322,10 @@
char *mailfrommsg;
char ipaddress[200];
+ struct addrinfo *ai; /* Lattest active connection */
+ int ismx;
+ struct addrinfo *ai_root; /* All lattest addresses */
+
char stdinbuf[8192];
int stdinsize; /* Available */
int stdincurs; /* Consumed */
@@ -365,7 +369,8 @@
extern int check_7bit_cleanness __((struct ctldesc *dp));
extern void notarystatsave __((SmtpState *SS, char *smtpstatline, char *status));
-extern int makeconn __((SmtpState *SS, struct addrinfo *, int));
+extern int makeconn __((SmtpState *SS, struct addrinfo *, int));
+extern int makereconn __((SmtpState *SS));
extern int vcsetup __((SmtpState *SS, struct sockaddr *, int*, char*));
#ifdef BIND
extern int rightmx __((const char*, const char*, void*));
@@ -2348,7 +2353,7 @@
if (i == EX_TEMPFAIL) {
/* There are systems, which hang up on us, when we
greet them with an "EHLO".. Do here a normal "HELO".. */
- i = smtpconn(SS, host, noMX);
+ i = makereconn(SS);
if (i != EX_OK)
continue;
i = EX_TEMPFAIL;
@@ -2374,7 +2379,7 @@
}
if (i == EX_TEMPFAIL) {
/* Ok, sometimes EHLO+HELO cause crash, open and do HELO only */
- i = smtpconn(SS, host, noMX);
+ i = makereconn(SS);
if (i != EX_OK)
continue;;
i = smtpwrite(SS, 1, SMTPbuf, 0, NULL);
@@ -2514,6 +2519,7 @@
SS->mxcount = 0;
retval = makeconn(SS, ai, -2);
+ ai = NULL; /* Don't free -- now */
} else {
@@ -2655,13 +2661,16 @@
"smtp; 500 (nameserver data inconsistency. All MXes rejected [we are the best?], no address: '%.200s')", host);
#if 1
zsyslog((LOG_ERR, "%s", SS->remotemsg));
- r = EX_NOHOST;
+ if (r != EX_TEMPFAIL)
+ r = EX_NOHOST;
#endif
} else if (gai_err == EAI_NONAME || gai_err == EAI_NODATA) {
sprintf(SS->remotemsg,
"smtp; 500 (nameserver data inconsistency. No MX, no address: '%.200s')",
host);
- r = EX_NOHOST; /* Can do instant reject */
+ zsyslog((LOG_ERR, "%s r=%d", SS->remotemsg, r));
+ if (r != EX_TEMPFAIL)
+ r = EX_NOHOST; /* Can do instant reject */
} else {
sprintf(SS->remotemsg,
"smtp; 500 (nameserver data inconsistency. No MX, no address: '%.200s', errno=%s, gai_errno='%s')",
@@ -2690,8 +2699,8 @@
notary_setwtt(buf);
}
retval = makeconn(SS, ai, -1);
- freeaddrinfo(ai);
- ai = NULL;
+ /* freeaddrinfo(ai); -- stored into the SS */
+ ai = NULL; /* Make sure we don't free the 'ai' chain below */
} else {
/* Has valid MX records, they have been suitably randomized
@@ -2708,6 +2717,8 @@
r = makeconn(SS, SS->mxh[i].ai, i);
SS->firstmx = i+1;
+ SS->mxh[i].ai = NULL; /* Save this chain into
+ internal SS context! */
if (r == EX_OK) {
retval = EX_OK;
break;
@@ -2721,8 +2732,11 @@
fprintf(logfp,
"%s#\tsmtpconn: retval = %d\n", logtag(), retval);
}
- if (ai != NULL)
- freeaddrinfo(ai);
+
+ if (retval != EX_OK)
+ if (ai != NULL)
+ freeaddrinfo(ai);
+
return retval;
}
@@ -2802,8 +2816,9 @@
}
#endif /* RFC974 */
#endif /* BIND */
+
- retval = EX_UNAVAILABLE;
+ retval = EX_TEMPFAIL;
#if 0
if (SS->verboselog) {
fprintf(SS->verboselog,"makeconn('%.200s') to IP addresses:", hostbuf);
@@ -2815,6 +2830,16 @@
fprintf(SS->verboselog,"\n");
}
#endif
+
+ /* discard old reconnect state */
+
+ if (SS->ai_root)
+ freeaddrinfo(SS->ai_root);
+
+ /* Save new reconnect state */
+
+ SS->ai_root = ai;
+
for ( ; ai && !getout ; ai = ai->ai_next ) {
int i = 0;
@@ -2823,6 +2848,10 @@
struct sockaddr_in6 *si6;
#endif
+ /* For possible reconnect */
+ SS->ai = ai;
+ SS->ismx = ismx;
+
if (ai->ai_family == AF_INET) {
si = (struct sockaddr_in *)ai->ai_addr;
i = matchmyaddress((struct sockaddr*)ai->ai_addr);
@@ -2869,6 +2898,7 @@
break;
}
sprintf(SS->remotemsg,"Trying to talk with myself!");
+ retval = EX_UNAVAILABLE;
break; /* TEMPFAIL or UNAVAILABLE.. */
}
@@ -2880,7 +2910,8 @@
}
- i = vcsetup(SS, /* (struct sockaddr *) */ ai->ai_addr, &mfd, hostbuf);
+ i = vcsetup(SS, /* (struct sockaddr*) */ ai->ai_addr, &mfd, hostbuf);
+ retval = i;
switch (i) {
case EX_OK:
@@ -2915,13 +2946,22 @@
retval = EX_TEMPFAIL;
break;
}
- }
+ } /* end of for-loop */
+
if (getout)
retval = EX_TEMPFAIL;
return retval;
}
int
+makereconn(SS)
+ SmtpState *SS;
+{
+ smtpclose(SS);
+ return makeconn(SS, SS->ai, SS->ismx);
+}
+
+int
vcsetup(SS, sa, fdp, hostname)
SmtpState *SS;
struct sockaddr *sa;
@@ -3822,8 +3862,7 @@
if (strncmp(SS->pipecmds[idx],
"RSET",4) != 0) /* If RSET, append to previous! */
SS->remotemsg[0] = 0;
- rmsgappend(SS,"\r<<- ");
- rmsgappend(SS,"%s", SS->pipecmds[idx]);
+ rmsgappend(SS,"\r<<- %s", SS->pipecmds[idx]);
} else {
strcpy(SS->remotemsg,"\r<<- (null)");
}
@@ -4165,8 +4204,7 @@
if (strbuf) {
if (strncmp(strbuf,"RSET",4) != 0) /* If RSET, append to previous! */
*SS->remotemsg = 0;
- rmsgappend(SS,"\r<<- ");
- rmsgappend(SS,"%s", strbuf);
+ rmsgappend(SS,"\r<<- %s", strbuf);
} else {
strcpy(SS->remotemsg,"\r<<- (null)");
}
@@ -4224,6 +4262,9 @@
if (*s != '\n')
break;
*s = '\0';
+
+ rmsgappend(SS,"\r->> %s",buf);
+
if (SS->within_ehlo)
ehlo_check(SS,&buf[4]);
if (!strbuf && !SS->esmtp_on_banner)
@@ -4324,7 +4365,7 @@
return EX_TEMPFAIL;
}
*--cp = '\0'; /* kill the LF */
- if ((cp - buf) < 4) {
+ if ((cp - buf) < 3) {
/* A '354<CRLR>' could be treated as ok... */
sprintf(SS->remotemsg, "smtp; 500 (SMTP response '%s' unexpected!)", buf);
time(&endtime);
@@ -4360,9 +4401,6 @@
if (!strbuf && !SS->esmtp_on_banner)
esmtp_banner_check(SS,&buf[4]);
- rmsgappend(SS,"\r->> %s",buf);
-
-
dflag = 0;
if (response >= 400)