aboutsummaryrefslogtreecommitdiffstats
path: root/etrn.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>1997-06-25 14:38:07 +0000
committerEric S. Raymond <esr@thyrsus.com>1997-06-25 14:38:07 +0000
commitfc59bdd5cdafecb895a6adc06c11da71cad6d19f (patch)
treecb7a43b8d0c352401b3b504ab39ccd6cb203d788 /etrn.c
parent33f99e6233ca2c325fed441bd255059ed3fbd32a (diff)
downloadfetchmail-fc59bdd5cdafecb895a6adc06c11da71cad6d19f.tar.gz
fetchmail-fc59bdd5cdafecb895a6adc06c11da71cad6d19f.tar.bz2
fetchmail-fc59bdd5cdafecb895a6adc06c11da71cad6d19f.zip
Guenther Leber's fix.
svn path=/trunk/; revision=1116
Diffstat (limited to 'etrn.c')
-rw-r--r--etrn.c139
1 files changed, 97 insertions, 42 deletions
diff --git a/etrn.c b/etrn.c
index 817b4187..790a6358 100644
--- a/etrn.c
+++ b/etrn.c
@@ -7,6 +7,8 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
+#include <netdb.h>
#include "fetchmail.h"
#include "smtp.h"
#include "socket.h"
@@ -23,11 +25,16 @@ static int etrn_ok (int sock, char *argbuf)
return(ok);
}
-static int etrn_getrange(int sock, struct query *ctl, int*countp, int*newp)
+static int etrn_getrange(int sock, struct query *ctl, char *id, int *countp,
+ int *newp)
/* send ETRN and interpret the response */
{
- int ok, opts;
- char buf [POPBUFSIZE+1];
+ int ok, opts, qdone = 0;
+ char buf [POPBUFSIZE+1],
+ hname[256];
+ const char *qname;
+ struct idlist *qnp; /* pointer to Q names */
+ struct hostent *hp;
if ((ok = SMTP_ehlo(sock, ctl->server.names->id, &opts)))
{
@@ -44,46 +51,94 @@ static int etrn_getrange(int sock, struct query *ctl, int*countp, int*newp)
*countp = *newp = -1; /* make sure we don't enter the fetch loop */
- /* ship the actual poll and get the response */
- gen_send(sock, "ETRN %s", ctl->smtphost);
- if ((ok = gen_recv(sock, buf, sizeof(buf))))
- return(ok);
-
- /* this switch includes all the response codes described in RFC1985 */
- switch(atoi(buf))
+ /*** This is a sort of horrible HACK because the ETRN protocol
+ *** does not fit very well into the mailbox concept used in
+ *** this program (IMHO). The last element of ctl->smtphunt
+ *** turned out to be the host being queried (i.e., the smtp server).
+ *** for that reason the rather "funny" condition in the for loop.
+ *** Isn't it sort of unreasonable to add the server to the ETRN
+ *** hunt list? (Concerning ETRN I'm sure! In case I want a Q-run of
+ *** my SMTP-server I can always specify -Smyserver, and this is only
+ *** resonable if I start sendmail without -qtime and in Q-only mode.)
+ ***
+ *** -- 1997-06-22 Guenther Leber
+ ***/
+ /* do it for all queues in the smtphunt list except the last one
+ which is the SMTP-server itself */
+ for (qnp = ctl->smtphunt; ( (qnp != (struct idlist *) NULL) &&
+ (qnp->next != (struct idlist *) NULL) ) || (qdone == 0);
+ qnp = qnp->next, qdone++)
{
- case 250: /* OK, queuing for node <x> started */
- error(0, 0, "Queuing for %s started", ctl->smtphost);
- break;
-
- case 251: /* OK, no messages waiting for node <x> */
- error(0, 0, "No messages waiting for %s", ctl->smtphost);
- return(PS_NOMAIL);
-
- case 252: /* OK, pending messages for node <x> started */
- case 253: /* OK, <n> pending messages for node <x> started */
- error(0, 0, "Pending messages for %s started");
- break;
-
- case 458: /* Unable to queue messages for node <x> */
- error(0, -1, "Unable to queue messages for node %s", ctl->smtphost);
- return(PS_PROTOCOL);
- case 459: /* Node <x> not allowed: <reason> */
- error(0, -1, "Node %s not allowed: %s", ctl->smtphost, buf);
- return(PS_AUTHFAIL);
-
- case 500: /* Syntax Error */
- error(0, -1, "ETRN syntax error");
- return(PS_PROTOCOL);
-
- case 501: /* Syntax Error in Parameters */
- error(0, -1, "ETRN syntax error in parameters");
- return(PS_PROTOCOL);
-
- default:
- error(0, -1, "Unknown ETRN error %d", atoi(buf));
- return(PS_PROTOCOL);
+ /* extract name of Q */
+ if ( (qnp != (struct idlist *) NULL) &&
+ (qnp->next != (struct idlist *) NULL) )
+ {
+ /* take Q-name given in smtp hunt list */
+ qname = qnp->id;
+ } else {
+ assert(qdone == 0);
+ /*** use fully qualified host name as Q name ***/
+ /* get hostname */
+ if (gethostname(hname, sizeof hname) != 0)
+ {
+ /* exit with error message */
+ error(5, errno, "gethostname");
+ }
+ /* in case we got a host basename (as we do in Linux),
+ make a FQDN of it */
+ hp = gethostbyname(hname);
+ if (hp == (struct hostent *) NULL)
+ {
+ /* exit with error message */
+ error(5, h_errno, "gethostbyname");
+ }
+ /* here it is */
+ qname = hp->h_name;
+ }
+
+
+ /* ship the actual poll and get the response */
+ gen_send(sock, "ETRN %s", qname);
+ if ((ok = gen_recv(sock, buf, sizeof(buf))))
+ return(ok);
+
+ /* this switch includes all the response codes described in RFC1985 */
+ switch(atoi(buf))
+ {
+ case 250: /* OK, queuing for node <x> started */
+ error(0, 0, "Queuing for %s started", qname);
+ break;
+
+ case 251: /* OK, no messages waiting for node <x> */
+ error(0, 0, "No messages waiting for %s", qname);
+ return(PS_NOMAIL);
+
+ case 252: /* OK, pending messages for node <x> started */
+ case 253: /* OK, <n> pending messages for node <x> started */
+ error(0, 0, "Pending messages for %s started", qname);
+ break;
+
+ case 458: /* Unable to queue messages for node <x> */
+ error(0, -1, "Unable to queue messages for node %s", qname);
+ return(PS_PROTOCOL);
+
+ case 459: /* Node <x> not allowed: <reason> */
+ error(0, -1, "Node %s not allowed: %s", qname, buf);
+ return(PS_AUTHFAIL);
+
+ case 500: /* Syntax Error */
+ error(0, -1, "ETRN syntax error");
+ return(PS_PROTOCOL);
+
+ case 501: /* Syntax Error in Parameters */
+ error(0, -1, "ETRN syntax error in parameters");
+ return(PS_PROTOCOL);
+
+ default:
+ error(0, -1, "Unknown ETRN error %d", atoi(buf));
+ return(PS_PROTOCOL);
+ }
}
return(0);
@@ -119,7 +174,7 @@ int doETRN (struct query *ctl)
fprintf(stderr, "Option --flush is not supported with ETRN\n");
return(PS_SYNTAX);
}
- if (ctl->mailboxes) {
+ if (ctl->mailboxes->id) {
fprintf(stderr, "Option --remote is not supported with ETRN\n");
return(PS_SYNTAX);
}