#include <net/socket.h>
#endif
#include <sys/types.h>
-#include <sys/time.h>
#ifdef HAVE_NET_SELECT_H /* AIX needs this */
#include <net/select.h>
#endif
+#ifdef HAVE_SYS_SELECT_H /* AIX 4.1, at least, needs this */
+#include <sys/select.h>
+#endif
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include "i18n.h"
#include "fetchmail.h"
+#include "sdump.h"
#include "smtp.h"
#include "socket.h"
{
int ok;
- ok = SMTP_ok(sock);
+ (void)argbuf;
+ ok = SMTP_ok(sock, SMTP_MODE, TIMEOUT_DEFAULT);
if (ok == SM_UNRECOVERABLE)
return(PS_PROTOCOL);
else
/* send ODMR and then run a reverse SMTP session */
{
int ok, opts, smtp_sock;
+ int doing_smtp_data = 0; /* Are we in SMTP DATA state? */
char buf [MSGBUFSIZE+1];
struct idlist *qnp; /* pointer to Q names */
- if ((ok = SMTP_ehlo(sock, fetchmailhost, &opts)))
+ (void)id;
+ if ((ok = SMTP_ehlo(sock, SMTP_MODE, fetchmailhost,
+ ctl->server.esmtp_name, ctl->server.esmtp_password,
+ &opts)))
{
- report(stderr, _("%s's SMTP listener does not support ESMTP\n"),
+ report(stderr, GT_("%s's SMTP listener does not support ESMTP\n"),
ctl->server.pollname);
return(ok);
}
else if (!(opts & ESMTP_ATRN))
{
- report(stderr, _("%s's SMTP listener does not support ATRN\n"),
+ report(stderr, GT_("%s's SMTP listener does not support ATRN\n"),
ctl->server.pollname);
return(PS_PROTOCOL);
}
* canonical DNS name.
*/
buf[0] = '\0';
- for (qnp = ctl->smtphunt; qnp; qnp = qnp->next)
+ for (qnp = ctl->domainlist; qnp; qnp = qnp->next)
if (strlen(buf) + strlen(qnp->id) + 1 >= sizeof(buf))
break;
else
switch(atoi(buf))
{
case 250: /* OK, turnaround is about to happe */
- if (outlevel >= O_SILENT)
- report(stdout, _("Turnaround now...\n"));
+ if (outlevel > O_SILENT)
+ report(stdout, GT_("Turnaround now...\n"));
break;
case 450: /* ATRN request refused */
- if (outlevel >= O_SILENT)
- report(stdout, _("ATRN request refused.\n"));
+ if (outlevel > O_SILENT)
+ report(stdout, GT_("ATRN request refused.\n"));
return(PS_PROTOCOL);
case 451: /* Unable to process ATRN request now */
- report(stderr, _("Unable to process ATRN request now\n"));
+ report(stderr, GT_("Unable to process ATRN request now\n"));
return(PS_EXCLUDE);
case 453: /* You have no mail */
- report(stderr, _("You have no mail.\n"));
+ if (outlevel > O_SILENT)
+ report(stderr, GT_("You have no mail.\n"));
return(PS_NOMAIL);
case 502: /* Command not implemented */
- report(stderr, _("Command not implemented\n"));
+ report(stderr, GT_("Command not implemented\n"));
return(PS_PROTOCOL);
case 530: /* Authentication required */
- report(stderr, _("Authentication required.\n"));
+ report(stderr, GT_("Authentication required.\n"));
return(PS_AUTHFAIL);
- default:
- report(stderr, _("Unknown ODMR error %d\n"), atoi(buf));
- return(PS_PROTOCOL);
+ default: {
+ char *t = sdump(buf, strlen(buf));
+ report(stderr, GT_("Unknown ODMR error \"%s\"\n"), t);
+ xfree(t);
+ return(PS_PROTOCOL);
+ }
}
/*
* OK, if we got here it's time to become a pipe between the ODMR
- * remote server (sending) and the local SMTP daemon (receiving).
- * We're npt going to try to be a protocol machine; instead, we'll
- * use select(2) to watch the read sides of both sockets and just
- * throw their data at each other.
- */
- /*
- * FIXME: we hardcode "localhost" here because ODMR is fighting
- * over the ETRN meaning of smtphost and the POP/IMAP meaning.
- * ODMR needs both meanings, but there is only one config var. So
- * for now ODMR always uses the "localhost" SMTP server to connect
- * with locally.
+ * remote server (sending) and the SMTP listener we've designated
+ * (receiving). We're not going to try to be a protocol machine;
+ * instead, we'll use select(2) to watch the read sides of both
+ * sockets and just throw their data at each other.
*/
- smtp_sock = SockOpen("localhost", SMTP_PORT, NULL, NULL);
- if (smtp_sock == -1)
+ if ((smtp_sock = smtp_setup(ctl)) == -1)
return(PS_SOCKET);
else
{
{
fd_set readfds;
struct timeval timeout;
- char buf[MSGBUFSIZE];
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
break;
SockWrite(smtp_sock, buf, n);
- if (outlevel >= O_MONITOR)
- report(stdout, "ODMR< %s\n", buf);
+ if (outlevel >= O_MONITOR && !doing_smtp_data)
+ report(stdout, "ODMR< %s", buf);
}
if (FD_ISSET(smtp_sock, &readfds))
{
SockWrite(sock, buf, n);
if (outlevel >= O_MONITOR)
- report(stdout, "ODMR> %s\n", buf);
+ report(stdout, "ODMR> %s", buf);
+
+ /* We are about to receive message data if the local MTA
+ * sends 354 (after receiving DATA) */
+ if (!doing_smtp_data && !strncmp(buf, "354", 3))
+ {
+ doing_smtp_data = 1;
+ if (outlevel > O_SILENT)
+ report(stdout, GT_("receiving message data\n"));
+ }
+ else if (doing_smtp_data)
+ doing_smtp_data = 0;
}
}
SockClose(smtp_sock);
static int odmr_logout(int sock, struct query *ctl)
/* send logout command */
{
- return(gen_transact(sock, "QUIT"));
+ /* if we have a smtp_socket, then we've turned around and the
+ local smtp server is in control of the connection (so we don't
+ send QUIT) */
+ if (ctl->smtp_socket == -1)
+ return(gen_transact(sock, "QUIT"));
+ else
+ return(PS_SUCCESS);
}
-const static struct method odmr =
+static const struct method odmr =
{
"ODMR", /* ODMR protocol */
-#if INET6_ENABLE
- "odmr", /* standard SMTP port */
- "odmrs", /* ssl SMTP port */
-#else /* INET6_ENABLE */
- 366, /* standard SMTP port */
- 2366, /* ssl SMTP port (BOGUS! RANDOM VALUE) */
-#endif /* INET6_ENABLE */
+ "odmr", /* standard ODMR port */
+ "odmrs", /* ssl ODMR port */
FALSE, /* this is not a tagged protocol */
FALSE, /* this does not use a message delimiter */
odmr_ok, /* parse command response */
NULL, /* no need to get authentication */
odmr_getrange, /* initialize message sending */
NULL, /* we cannot get a list of sizes */
+ NULL, /* we cannot get a list of sizes of subsets */
NULL, /* how do we tell a message is old? */
NULL, /* no way to fetch headers */
NULL, /* no way to fetch body */
NULL, /* no message trailer */
NULL, /* how to delete a message */
+ NULL, /* how to mark a message as seen */
+ NULL, /* no mailbox support */
odmr_logout, /* log out, we're done */
FALSE, /* no, we can't re-poll */
};
int status;
if (ctl->keep) {
- fprintf(stderr, _("Option --keep is not supported with ODMR\n"));
+ fprintf(stderr, GT_("Option --keep is not supported with ODMR\n"));
return(PS_SYNTAX);
}
if (ctl->flush) {
- fprintf(stderr, _("Option --flush is not supported with ODMR\n"));
+ fprintf(stderr, GT_("Option --flush is not supported with ODMR\n"));
return(PS_SYNTAX);
}
if (ctl->mailboxes->id) {
- fprintf(stderr, _("Option --remote is not supported with ODMR\n"));
+ fprintf(stderr, GT_("Option --folder is not supported with ODMR\n"));
return(PS_SYNTAX);
}
if (check_only) {
- fprintf(stderr, _("Option --check is not supported with ODMR\n"));
+ fprintf(stderr, GT_("Option --check is not supported with ODMR\n"));
return(PS_SYNTAX);
}
peek_capable = FALSE;