]> Pileus Git - ~andy/fetchmail/commitdiff
Add full IMAP4 capability.
authorEric S. Raymond <esr@thyrsus.com>
Mon, 9 Dec 1996 17:43:09 +0000 (17:43 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 9 Dec 1996 17:43:09 +0000 (17:43 -0000)
svn path=/trunk/; revision=620

NEWS
driver.c
fetchmail.h
imap.c
pop2.c
pop3.c

diff --git a/NEWS b/NEWS
index dfb1bc88410a7267fd8f362bac8b8700f3b1b542..81d05218af9eee3232185d41700887e7618dfad5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,15 @@
                        Release Notes:
 
+------------------------------------------------------------------------------
+fetchmail-2.3 ()
+
+features -- 
+
+* Full IMAP4 support -- we now probe for IMAP4 capabilities and use 
+  RFC822.PEEK when possible to avoid marking messages seen on the server
+  before they are deleted.  This improves recovery from sendmail and
+  dropped-connection errors.
+
 ------------------------------------------------------------------------------
 fetchmail-2.2 (Mon Dec  9 00:15:01 EST 1996):
 
index 8d673078c37854b0fc460e6785a2468f366ea2b7..b85b4e14a29f19d57d321b91598ccd885348bed5 100644 (file)
--- a/driver.c
+++ b/driver.c
@@ -47,6 +47,7 @@
 
 int batchlimit;                /* how often to tear down the delivery connection */
 int batchcount;                /* count of messages sent in current batch */
+int peek_capable;      /* can we peek for better error recovery? */
 
 static const struct method *protocol;
 static jmp_buf restart;
@@ -935,16 +936,19 @@ const struct method *proto;       /* protocol method table */
        else if (count > 0)
        {    
            /*
-            * What forces this code is that in POP3 you can't fetch a
-            * message without having it marked `seen'.
+            * What forces this code is that in POP3 and IMAP2BIS you can't
+            * fetch a message without having it marked `seen'.  In IMAP4,
+            * on the other hand, you can (peek_capable is set to convey
+            * this).
             *
-            * The result is that if there's any kind of transient error
-            * (DNS lookup failure, or sendmail refusing delivery due to
-            * process-table limits) the message will be marked "seen" on
-            * the server without having been delivered.  This is not a
-            * big problem if fetchmail is running in foreground, because
-            * the user will see a "skipped" message when it next runs and
-            * get clued in.
+            * The result of being unable to peek is that if there's
+            * any kind of transient error (DNS lookup failure, or
+            * sendmail refusing delivery due to process-table limits)
+            * the message will be marked "seen" on the server without
+            * having been delivered.  This is not a big problem if
+            * fetchmail is running in foreground, because the user
+            * will see a "skipped" message when it next runs and get
+            * clued in.
             *
             * But in daemon mode this leads to the message being silently
             * ignored forever.  This is not acceptable.
@@ -953,7 +957,7 @@ const struct method *proto; /* protocol method table */
             * previous pass and forcing all messages to be considered new
             * if it's nonzero.
             */
-           int force_retrieval = (ctl->errcount > 0);
+           int force_retrieval = !peek_capable && (ctl->errcount > 0);
 
            ctl->errcount = 0;
 
index 13b9791f4ee6296c747ea4b1b84b28ca6c5ab67e..9e10cd0d188dd28916d2c260670def0af47640aa 100644 (file)
@@ -149,6 +149,7 @@ extern char *cmd_logfile;   /* if --logfile was set */
 /* these get computed */
 extern int batchlimit;         /* if --batchlimit was set */
 extern int batchcount;         /* count of messages sent in current batch */
+extern int peek_capable;       /* can we read msgs without setting seen? */
 
 /* miscellaneous global controls */
 extern char *rcfile;           /* path name of rc file */
diff --git a/imap.c b/imap.c
index ec529cf143dd5180ab30962109b44e1461a7df95..12f537194c03717f34e683cc1439b8fd193e9ff3 100644 (file)
--- a/imap.c
+++ b/imap.c
@@ -1,5 +1,5 @@
 /*
- * imap.c -- IMAP2bis protocol methods
+ * imap.c -- IMAP2bis/IMAP4 protocol methods
  *
  * Copyright 1996 by Eric S. Raymond
  * All rights reserved.
@@ -16,7 +16,7 @@
 #include  "socket.h"
 #include  "fetchmail.h"
 
-static int count, seen, recent, unseen;
+static int count, seen, recent, unseen, imap4;
 
 int imap_ok (FILE *sockfp,  char *argbuf)
 /* parse command response */
@@ -74,9 +74,17 @@ int imap_getauth(FILE *sockfp, struct query *ctl, char *buf)
 /* apply for connection authorization */
 {
     /* try to get authorized */
-    return(gen_transact(sockfp,
+    int ok = gen_transact(sockfp,
                  "LOGIN %s \"%s\"",
-                 ctl->remotename, ctl->password));
+                 ctl->remotename, ctl->password);
+
+    if (ok)
+       return(ok);
+
+    /* probe to see if we're running IMAP4 and can use RFC822.PEEK */
+    imap4 = ((gen_transact(sockfp, "CAPABILITY")) == 0);
+
+    return(0);
 }
 
 static int imap_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp)
@@ -144,7 +152,16 @@ static int imap_fetch(FILE *sockfp, int number, int *lenp)
     char buf [POPBUFSIZE+1];
     int        num;
 
-    gen_send(sockfp, "FETCH %d RFC822", number);
+    /*
+     * If we're using IMAP4, we can fetch the message without setting its
+     * seen flag.  This is good!  It means that if the protocol exchange
+     * craps out during the message, it will still be marked `unseen' on
+     * the server 
+     */
+    if (imap4)
+       gen_send(sockfp, "FETCH %d RFC822.PEEK", number);
+    else
+       gen_send(sockfp, "FETCH %d RFC822", number);
 
     /* looking for FETCH response */
     do {
@@ -173,7 +190,12 @@ static int imap_trail(FILE *sockfp, struct query *ctl, int number)
 static int imap_delete(FILE *sockfp, struct query *ctl, int number)
 /* set delete flag for given message */
 {
-    return(gen_transact(sockfp, "STORE %d +FLAGS (\\Deleted)", number));
+    /* use SILENT if possible as a minor throughput optimization */
+    return(gen_transact(sockfp,
+                       imap4 
+                               ? "STORE %d +FLAGS.SILENT (\\Deleted)"
+                               : "STORE %d +FLAGS (\\Deleted)", 
+                       number));
 }
 
 const static struct method imap =
diff --git a/pop2.c b/pop2.c
index 35f69fbd87b888ac5afc06d218dcfc38c3a19bb1..bb668ad95a3f81e2b478d7220337c56808900bae 100644 (file)
--- a/pop2.c
+++ b/pop2.c
@@ -131,6 +131,7 @@ const static struct method pop2 =
 int doPOP2 (struct query *ctl)
 /* retrieve messages using POP2 */
 {
+    peek_capable = FALSE;
     return(do_protocol(ctl, &pop2));
 }
 
diff --git a/pop3.c b/pop3.c
index 8f5a1a16d2cca803e9b2c909c0c528e8c1408d29..1e429d304af9753d24cb652f03a19314280bd8b4 100644 (file)
--- a/pop3.c
+++ b/pop3.c
@@ -276,6 +276,7 @@ int doPOP3 (struct query *ctl)
        fprintf(stderr,"Option --remote is not supported with POP3\n");
        return(PS_SYNTAX);
     }
+    peek_capable = FALSE;
     return(do_protocol(ctl, &pop3));
 }