improve logic for header-stripping in MIME.java
[org.ibex.mail.git] / src / org / ibex / mail / IMAP.java
index 6ac7280..5f0d11e 100644 (file)
@@ -14,6 +14,8 @@ import java.net.*;
 import java.text.*;
 import java.io.*;
  
+// FEATURE: IDLE extension for blackberries
+
 // FIXME: this is valid    LSUB "" asdfdas%*%*%*%*SFEFGWEF
 // FIXME: be very careful about where/when we quotify stuff
 // FIXME: 'UID FOO 100:*' must match at least one message even if all UIDs less than 100
@@ -155,7 +157,7 @@ public class IMAP {
             }
         }
 
-        public String[] capability() { return new String[] { "IMAP4rev1" , "UNSELECT", "ID" }; }
+        public String[] capability() { return new String[] { "IMAP4rev1" , "UNSELECT" /*, "ID"*/ }; }
         public Hashtable id(Hashtable clientId) {
             Hashtable response = new Hashtable();
             response.put("name", IMAP.class.getName());
@@ -310,10 +312,10 @@ public class IMAP {
                     case EXPUNGE:      selected(); api.expunge(); break;
                     case UNSELECT:     selected(); api.unselect(); selected = false; break;
                     case CREATE:       api.create(token().astring()); break;
-                    case FETCH:        selected(); fetch(((lastuid=uid)
-                                                          ? Query.uid(token().set(maxn(uid)))
-                                                          : Query.imapNumber(token().set(maxn(uid)))),
-                                                        lastfetch=token().lx(), 0, 0, 0, uid, 0); break;
+                    case FETCH:        selected(); lastuid = uid; fetch((uid
+                                                                         ? Query.uid(token().set(maxn(uid)))
+                                                                         : Query.imapNumber(token().set(maxn(uid)))),
+                                                                        lastfetch=token().lx(), 0, 0, 0, uid, 0); break;
                     case COPY:         selected(); api.copy(uid
                                                             ? Query.uid(token().set(maxn(uid)))
                                                             : Query.imapNumber(token().set(maxn(uid))), token().astring()); break;
@@ -358,7 +360,8 @@ public class IMAP {
                         Date arrival = new Date();
                         Parser.Token t = token();
                         if (t.type == t.LIST)   { flags = t.flags();      t = token(); }
-                        if (t.type != t.QUOTED) { arrival = t.datetime(); t = token(); }
+                        Parser.Token t2 = token(false);
+                        if (t2 != null) { arrival = t.datetime(); t = t2; }
                         api.append(m, flags, arrival, t.q());
                         break; }
                     case STORE: {
@@ -385,7 +388,10 @@ public class IMAP {
                     return;
                 }
             } catch (Server.Bad b) { println(tag==null ? "* BAD Invalid tag":(tag + " Bad " + b.toString())); Log.warn(this,b);
-            } catch (Server.No n)  { println(tag==null?"* BAD Invalid tag":(tag+" No "  + n.toString())); Log.warn(this,n); }
+            } catch (Server.No n)  { println(tag==null?"* BAD Invalid tag":(tag+" No "  + n.toString())); Log.warn(this,n);
+            } finally {
+                //Log.warn(this, conn.dumpLog()+"\n");
+            }
         }
 
         private Parser.Token[] lastfetch = null; // hack
@@ -449,6 +455,7 @@ public class IMAP {
                     t = new Parser.Token[] { parser.token("FLAGS"), parser.token("INTERNALDATE"),
                                       parser.token("RFC822.SIZE") };
             }
+            boolean looked_at_body = false;
             for(int i=0; i<t.length; i++) {
                 if (r.length() > initlen) r.append(" ");
                 if (t[i] == null || t[i].s == null) continue;
@@ -466,11 +473,11 @@ public class IMAP {
                 } else if (!(s.equals("BODY.PEEK") || s.equals("BODY"))) { throw new Server.No("unknown fetch argument: " + s);
                 } else {
                     if (s.equalsIgnoreCase("BODY.PEEK"))   spec |= PEEK;
-                    //else if (e) api.addFlags(Query.imapNumber(new int[] { num, num }), Mailbox.Flag.SEEN, false, false);
+                    looked_at_body = true;
                     if (i >= t.length - 1 || t[i+1].type != Parser.Token.LIST) {
                        spec |= BODYSTRUCTURE;
                        if (e) { r.append(" "); r.append(Printer.bodystructure(m)); } continue;
-                       //{ if (e) { r.append(" "); r.append(Printer.qq(m.body)); } continue; }
+                       //if (e) { r.append(" "); r.append(Printer.qq(m.getBody().getStream())); } continue;
                    }
                     Fountain payload = Fountain.Util.create("");
                     r.append("[");
@@ -500,6 +507,8 @@ public class IMAP {
                     if (e) { r.append("] "); r.append(Printer.qq(payload.getStream())); }
                 }
             }
+            if ((spec & PEEK) == 0 && looked_at_body && e)
+                api.addFlags(Query.imapNumber(new int[] { num, num }), Mailbox.Flag.SEEN, false, false);
             if (e) {
                r.append(")");
                println("* " + r.toString());
@@ -702,7 +711,7 @@ public class IMAP {
             }
             public Date datetime() {
                 if (type != QUOTED) bad("Expected quoted datetime");
-                try { return new SimpleDateFormat("dd-MM-yyyy hh:mm:ss zzzz").parse(s.trim());
+                try { return new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss zzzz").parse(s.trim());
                 } catch (ParseException p) { throw new Server.Bad("invalid datetime format " + s + " : " + p); }
             }
             public String atom() {
@@ -827,6 +836,12 @@ public class IMAP {
                 ")";
         }
         
+        // FIXME: ugly
+        public static String qq(Stream stream) {
+            StringBuffer sb = new StringBuffer();
+            stream.transcribe(sb);
+            return qq(sb.toString());
+        }
         public static String qq(String s) {
             StringBuffer ret = new StringBuffer();
             ret.append('{');