]> Pileus Git - ~andy/fetchmail/blobdiff - odmr.c
Attempt merging from 6.3.24.
[~andy/fetchmail] / odmr.c
diff --git a/odmr.c b/odmr.c
index c712ccb85d2d06fb03e2c251486600bf0be782d5..64e70bcebb3e1af0311fec11474b48d24dc328ea 100644 (file)
--- a/odmr.c
+++ b/odmr.c
@@ -9,19 +9,15 @@
 #include  <stdio.h>
 #include  <stdlib.h>
 #include  <assert.h>
-#ifdef HAVE_NET_SOCKET_H /* BeOS needs this */
-#include <net/socket.h>
-#endif
+#include <string.h>
 #include  <sys/types.h>
-#include  <sys/time.h>
-#ifdef HAVE_NET_SELECT_H /* AIX needs this */
-#include <net/select.h>
-#endif
+#include  <sys/select.h>
 #include  <netdb.h>
 #include  <errno.h>
 #include  <unistd.h>
-#include  "i18n.h"
+#include  "gettext.h"
 #include  "fetchmail.h"
+#include  "sdump.h"
 #include  "smtp.h"
 #include  "socket.h"
 
@@ -30,7 +26,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
@@ -42,18 +39,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);
     }
@@ -62,7 +63,7 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id,
     *bytes = *countp = *newp = -1;
 
     /* authenticate via CRAM-MD5 */
-    ok = do_cram_md5(sock, "AUTH", ctl);
+    ok = do_cram_md5(sock, "AUTH", ctl, "334 ");
     if (ok)
        return(ok);
 
@@ -71,7 +72,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
@@ -90,45 +91,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.
+     * 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(ctl->smtphost, SMTP_PORT, NULL, NULL);
-    if (smtp_sock == -1)
+    if ((smtp_sock = smtp_setup(ctl)) == -1)
        return(PS_SOCKET);
     else
     {
@@ -138,7 +142,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);
@@ -157,8 +160,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))
            {
@@ -168,7 +171,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);
@@ -177,28 +191,38 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id,
     return(0);
 }
 
-const static struct method odmr =
+static int odmr_logout(int sock, struct query *ctl)
+/* send logout command */
+{
+    /* 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);
+}
+
+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,              /* log out, we're done */
+    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 */
 };
 
@@ -208,19 +232,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;