Author: dbkr
Date: 2006-08-08 22:45:23 +0000 (Tue, 08 Aug 2006)
New Revision: 9975

Modified:
   trunk/apps/Freemail/src/freemail/Freemail.java
   trunk/apps/Freemail/src/freemail/imap/IMAPHandler.java
   trunk/apps/Freemail/src/freemail/imap/IMAPMessageFlags.java
Log:
Build 2: Outlook Express compatability (finally) and general IMAP fixes.


Modified: trunk/apps/Freemail/src/freemail/Freemail.java
===================================================================
--- trunk/apps/Freemail/src/freemail/Freemail.java      2006-08-08 20:54:04 UTC 
(rev 9974)
+++ trunk/apps/Freemail/src/freemail/Freemail.java      2006-08-08 22:45:23 UTC 
(rev 9975)
@@ -12,7 +12,7 @@
        // version info
        public static final int VER_MAJOR = 0;
        public static final int VER_MINOR = 1;
-       public static final int BUILD_NO = 1;
+       public static final int BUILD_NO = 2;
        public static final String VERSION_TAG = "Pet Shop";

        private static final String TEMPDIRNAME = "temp";

Modified: trunk/apps/Freemail/src/freemail/imap/IMAPHandler.java
===================================================================
--- trunk/apps/Freemail/src/freemail/imap/IMAPHandler.java      2006-08-08 
20:54:04 UTC (rev 9974)
+++ trunk/apps/Freemail/src/freemail/imap/IMAPHandler.java      2006-08-08 
22:45:23 UTC (rev 9975)
@@ -8,6 +8,8 @@
 import java.io.IOException;
 import java.util.SortedMap;
 import java.lang.NumberFormatException;
+import java.text.SimpleDateFormat;
+import java.util.Date;

 import freemail.MessageBank;
 import freemail.MailMessage;
@@ -15,6 +17,8 @@
 import freemail.utils.EmailAddress;

 public class IMAPHandler implements Runnable {
+       private static final String CAPABILITY = "IMAP4rev1 AUTH=LOGIN";
+
        final Socket client;
        final OutputStream os;
        final PrintStream ps;
@@ -53,7 +57,7 @@
        }

        private void sendWelcome() {
-               this.ps.print("* OK [CAPABILITY IMAP4rev1] Freemail ready - hit 
me with your rhythm stick.\r\n");
+               this.ps.print("* OK [CAPABILITY "+CAPABILITY+"] Freemail ready 
- hit me with your rhythm stick.\r\n");
        }

        private void dispatch(IMAPMessage msg) {
@@ -84,6 +88,8 @@
                        this.handle_namespace(msg);
                } else if (msg.type.equals("lsub")) {
                        this.handle_lsub(msg);
+               } else if (msg.type.equals("status")) {
+                       this.handle_status(msg);
                } else {
                        this.reply(msg, "NO Sorry - not implemented");
                }
@@ -110,7 +116,7 @@
        }

        private void handle_capability(IMAPMessage msg) {
-               this.sendState("CAPABILITY IMAP4rev1 AUTH=LOGIN");
+               this.sendState("CAPABILITY "+CAPABILITY);

                this.reply(msg, "OK Capability completed");
        }
@@ -147,7 +153,7 @@
                if (mbname == null) {
                        // return hierarchy delimiter
                        this.sendState("LIST (\\Noselect) \".\" \"\"");
-               } else if (mbname.equals("%") || mbname.equals("INBOX")) {
+               } else if (mbname.equals("%") || mbname.equals("INBOX") || 
mbname.equals("*") || mbname.equals("INBOX*")) {
                        this.sendState("LIST (\\NoInferiors) \".\" \"INBOX\"");
                }

@@ -169,8 +175,8 @@
                mbname = trimQuotes(msg.args[0]).toLowerCase();

                if (mbname.equals("inbox")) {
-                       this.sendState("FLAGS (\\Recent \\Seen)");
-                       this.sendState("OK [PERMANENTFLAGS (\\*)]");
+                       this.sendState("FLAGS 
("+IMAPMessageFlags.getAllFlagsAsString()+")");
+                       this.sendState("OK [PERMANENTFLAGS (\\* 
"+IMAPMessageFlags.getPermanentFlagsAsString()+")] Limited");

                        SortedMap msgs = this.mb.listMessages();

@@ -193,6 +199,7 @@
                        this.sendState(numexists+" EXISTS");
                        this.sendState(numrecent+" RECENT");

+                       this.sendState("OK [UIDVALIDITY 1] Ok");

                        this.reply(msg, "OK [READ-WRITE] Done");
                } else {
@@ -316,7 +323,9 @@

                int msgnum = 1;
                if (msg.args[0].toLowerCase().equals("fetch")) {
+                       int oldsize = msgs.size();
                        msgs = msgs.tailMap(new Integer(from));
+                       msgnum += (oldsize - msgs.size());
                        while (msgs.size() > 0) {
                                Integer curuid = (Integer)msgs.firstKey();
                                if (curuid.intValue() > to) {
@@ -444,6 +453,15 @@
                        this.ps.print(a.substring(0, "rfc822.header".length()));
                        this.ps.flush();
                        return this.sendBody(mmsg, "header");
+               } else if (attr.startsWith("internaldate")) {
+                       val = mmsg.getFirstHeader("Date");
+                       if (val == null) {
+                               // possibly should keep our own dates...
+                               SimpleDateFormat sdf = new SimpleDateFormat("dd 
MMM yyyy HH:mm:ss Z");
+                               
+                               val = sdf.format(new Date());
+                       }
+                       val = "\""+val+"\"";
                }

                if (val == null)
@@ -497,6 +515,7 @@
                                for (int j = 0; j < fields.length; j++) {
                                        buf.append(mmsg.getHeaders(fields[j]));
                                }
+                               if (buf.length() == 0) buf.append("\r\n");
                        } else if (parts[i].equalsIgnoreCase("header")) {
                                // send all the header fields
                                try {
@@ -652,6 +671,83 @@
                this.reply(msg, "OK Namespace completed");
        }

+       private void handle_status(IMAPMessage msg) {
+               if (!this.verify_auth(msg)) {
+                       return;
+               }
+               
+               if (msg.args.length < 2) {
+                       this.reply(msg, "BAD Not enough arguments");
+                       return;
+               }
+               
+               String mbname = trimQuotes(msg.args[0]);
+               
+               // for now
+               if (!mbname.equalsIgnoreCase("INBOX")) {
+                       this.reply(msg, "BAD No such mailbox");
+                       return;
+               }
+               
+               SortedMap msgs = this.mb.listMessages();
+               
+               // gather statistics
+               int numrecent = 0;
+               int numunseen = 0;
+               int nummessages = msgs.size();
+               int lastuid = 0;
+               while (msgs.size() > 0) {
+                       Integer current = (Integer)(msgs.firstKey());
+                       MailMessage m =(MailMessage)msgs.get(msgs.firstKey());
+                               
+                       // if it's recent, add to the tally
+                       if (m.flags.get("\\Recent")) numrecent++;
+                       
+                       // is it unseen?
+                       if (!m.flags.get("\\Seen")) numunseen++;
+                       
+                       if (m.getUID() > lastuid) lastuid = m.getUID();
+                               
+                       msgs = msgs.tailMap(new Integer(current.intValue()+1));
+               }
+               
+               StringBuffer buf = new StringBuffer();
+               buf.append("STATUS ");
+               buf.append(msg.args[0]);
+               buf.append(" (");
+               
+               
+               // output the required information
+               int i;
+               boolean first = true;
+               for (i = 1; i < msg.args.length; i++) {
+                       String arg = msg.args[i];
+                       
+                       if (arg.startsWith("(")) arg = arg.substring(1);
+                       if (arg.endsWith(")")) arg = arg.substring(0, 
arg.length() - 1);
+                       
+                       if (!first) buf.append(" ");
+                       first = false;
+                       buf.append(arg);
+                       buf.append(" ");
+                       if (arg.equalsIgnoreCase("messages")) {
+                               buf.append(Integer.toString(nummessages));
+                       } else if (arg.equalsIgnoreCase("recent")) {
+                               buf.append(Integer.toString(numrecent));
+                       } else if (arg.equalsIgnoreCase("unseen")) {
+                               buf.append(Integer.toString(numunseen));
+                       } else if (arg.equalsIgnoreCase("uidnext")) {
+                               buf.append(Integer.toString(lastuid + 1));
+                       } else if (arg.equalsIgnoreCase("uidvalidity")) {
+                               buf.append("1");
+                       }
+               }
+               
+               buf.append(")");
+               this.sendState(buf.toString());
+               this.reply(msg, "OK STATUS completed");
+       }
+       
        private String getEnvelope(MailMessage mmsg) {
                StringBuffer buf = new StringBuffer("(");


Modified: trunk/apps/Freemail/src/freemail/imap/IMAPMessageFlags.java
===================================================================
--- trunk/apps/Freemail/src/freemail/imap/IMAPMessageFlags.java 2006-08-08 
20:54:04 UTC (rev 9974)
+++ trunk/apps/Freemail/src/freemail/imap/IMAPMessageFlags.java 2006-08-08 
22:45:23 UTC (rev 9975)
@@ -22,6 +22,44 @@
                "\\Draft",
                "\\Recent",
        };
+       
+       public static final String[] permanentFlags = {
+               "\\Answered",
+               "\\Flagged",
+               "\\Deleted",
+               "\\Draft",
+               "\\Recent",
+       };
+       
+       public static String getAllFlagsAsString() {
+               int i;
+               StringBuffer buf = new StringBuffer();
+               boolean first = true;
+               
+               for (i = 0; i < allFlags.length; i++) {
+                       if (!first)
+                               buf.append(" ");
+                       first = false;
+                       buf.append(allFlags[i]);
+               }
+               
+               return buf.toString();
+       }
+       
+       public static String getPermanentFlagsAsString() {
+               int i;
+               StringBuffer buf = new StringBuffer();
+               boolean first = true;
+               
+               for (i = 0; i < permanentFlags.length; i++) {
+                       if (!first)
+                               buf.append(" ");
+                       first = false;
+                       buf.append(permanentFlags[i]);
+               }
+               
+               return buf.toString();
+       }

        private Vector flags;



Reply via email to