fix handling of LIST/LSUB in IMAP
[org.ibex.mail.git] / src / org / ibex / mail / protocol / IMAP.java
index c84fa78..22ff402 100644 (file)
@@ -127,6 +127,10 @@ public class IMAP {
         public void lsub(String start, String ref) { list(start, ref, true); }
         public void list(String start, String ref) { list(start, ref, false); }
         public void list(String start, String ref, boolean lsub) {
+
+            // FIXME this might be wrong
+            if (ref.equalsIgnoreCase("inbox")) { client.list(sep,"inbox",lsub,false); return; }
+
             if (ref.length() == 0) { client.list(sep, start, lsub, false); return; }
             while (start.endsWith(""+sep)) start = start.substring(0, start.length() - 1);
             if (ref.endsWith("%")) ref = ref + sep;
@@ -134,19 +138,22 @@ public class IMAP {
             for(int i=0; i<children.length; i++) {
                 String s = children[i], pre = ref, kid = start + (start.length() > 0 ? sep+"" : "") + s;                
                 if (mailbox(kid, false) == null) continue;
-                boolean phantom = mailbox(kid, false).phantom();
-                while(true) {
-                    if (pre.length() == 0) {
-                        if (s.length() == 0)       client.list(sep, kid, lsub, phantom);
-                    } else switch(pre.charAt(0)) {
-                        case sep:        if (s.length() == 0) list(kid, pre.substring(1), lsub);                    break;
-                        case '%':        client.list(sep,kid,lsub,phantom);pre=pre.substring(1); s = "";            continue;
-                        case '*':        client.list(sep,kid,lsub,phantom);list(kid,pre,lsub);pre=pre.substring(1); break;
-                        default:         if (s.length()==0)                                                         break;
-                                         if (s.charAt(0) != pre.charAt(0))                                          break;
-                                         s = s.substring(1); pre = pre.substring(1);                                continue;
+                Mailbox phant = mailbox(kid, false, false);
+                if (phant != null) {
+                    boolean phantom = phant.phantom();
+                    while(true) {
+                        if (pre.length() == 0) {
+                            if (s.length() == 0)       client.list(sep, kid, lsub, phantom);
+                        } else switch(pre.charAt(0)) {
+                            case sep:        if (s.length() == 0) list(kid, pre.substring(1), lsub);                    break;
+                            case '%':        client.list(sep,kid,lsub,phantom);pre=pre.substring(1); s = "";            continue;
+                            case '*':        client.list(sep,kid,lsub,phantom);list(kid,pre,lsub);pre=pre.substring(1); break;
+                            default:         if (s.length()==0)                                                         break;
+                                if (s.charAt(0) != pre.charAt(0))                                          break;
+                                s = s.substring(1); pre = pre.substring(1);                                continue;
+                        }
+                        break;
                     }
-                    break;
                 }
             }
         }
@@ -194,10 +201,8 @@ public class IMAP {
         public int count(String mailbox)       { return mailbox(mailbox, false).count(Query.all()); }
         public int count()                     { return selected().count(Query.all()); }
         public int uidNext(String mailbox)     { return mailbox(mailbox, false).uidNext(); }
-        public int uidValidity(String mailbox) { return mailbox(mailbox, false).uidValidity(); }
-        public void select(String mailbox, boolean examineOnly) {
-           selected = mailbox(mailbox, false);
-       }
+        public int uidValidity(String mailbox) { return Math.abs(mailbox(mailbox, false).uidValidity()); }
+        public void select(String mailbox, boolean examineOnly) { selected = mailbox(mailbox, false); }
 
         public int[] search(Query q, boolean uid) {
             Vec.Int vec = new Vec.Int();
@@ -279,7 +284,7 @@ public class IMAP {
             parser = new Parser(conn);
             conn.setTimeout(30 * 60 * 1000);
             println("* OK " + conn.vhost + " " + IMAP.class.getName() + " IMAP4rev1 [RFC3501] v" + version + " server ready");
-            for(String tag = null;; newline()) try {
+            for(String tag = null;;) try {
                 conn.flush();
                 boolean uid = false;
                 tag = null; Parser.Token tok = token(); if (tok == null) return; tag = tok.astring();
@@ -367,9 +372,14 @@ public class IMAP {
                 }
                 println(tag+" OK "+command+" Completed. " +
                         (commandKey == LOGIN ? ("[CAPABILITY "+Printer.join(" ", api.capability())+"]") : ""));
-                Log.error("[imap]", conn.dumpLog());
-            } catch (Server.Bad b) { println(tag==null ? "* BAD Invalid tag":(tag + " Bad " + b.toString()));
-            } catch (Server.No n)  { println(tag==null?"* BAD Invalid tag":(tag+" No "  + n.toString())); }
+                try {
+                    newline();
+                } catch (Stream.EOF e) {
+                    Log.info(this, "connection closed");
+                    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); }
         }
 
         private Parser.Token[] lastfetch = null; // hack
@@ -696,12 +706,7 @@ public class IMAP {
             }
         }
 
-        public void newline() {
-           while (stream.peekc() == '\r' || stream.peekc() == '\n' || stream.peekc() == ' ') {
-               for(char c = stream.peekc(); c == ' ';) { stream.getc(); c = stream.peekc(); };
-               for(char c = stream.peekc(); c == '\r' || c == '\n';) { stream.getc(); c = stream.peekc(); };
-           }
-        }
+        public void newline() { stream.readln(); }
 
         public Token token() { return token(true); }
         public Token token(boolean freak) {