X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=odmr.c;h=d495e9cd0223713270710c20acb0a601c75f4178;hb=91644ff0b2e6eb3b26c5544a4a769ca4aaf08a14;hp=e97a755e1d8167db8d493d06137751bcd1937f1a;hpb=6006dd080700778ae0e7cefc4e56b5e800e8db1e;p=~andy%2Ffetchmail diff --git a/odmr.c b/odmr.c index e97a755e..d495e9cd 100644 --- a/odmr.c +++ b/odmr.c @@ -16,15 +16,18 @@ #include #endif #include -#include #ifdef HAVE_NET_SELECT_H /* AIX needs this */ #include #endif +#ifdef HAVE_SYS_SELECT_H /* AIX 4.1, at least, needs this */ +#include +#endif #include #include #include #include "i18n.h" #include "fetchmail.h" +#include "sdump.h" #include "smtp.h" #include "socket.h" @@ -33,7 +36,8 @@ static int odmr_ok (int sock, char *argbuf) { int ok; - ok = SMTP_ok(sock); + (void)argbuf; + ok = SMTP_ok(sock, SMTP_MODE, TIMEOUT_DEFAULT); if (ok == SM_UNRECOVERABLE) return(PS_PROTOCOL); else @@ -45,18 +49,22 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, /* 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); } @@ -74,7 +82,7 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, * 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 @@ -93,52 +101,48 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, 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 { @@ -148,7 +152,6 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, { fd_set readfds; struct timeval timeout; - char buf[MSGBUFSIZE]; FD_ZERO(&readfds); FD_SET(sock, &readfds); @@ -167,8 +170,8 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, 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)) { @@ -178,7 +181,18 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, 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); @@ -190,30 +204,34 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, 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 */ }; @@ -224,19 +242,19 @@ int doODMR (struct query *ctl) 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;