+
+
+ // Unparsing (printing) logic //////////////////////////////////////////////////////////////////////////////
+
+ static String quotify(String s){return s==null?"NIL":"\""+s.replaceAll("\\\\","\\\\").replaceAll("\"","\\\\\"")+"\"";}
+ static String quotify(Date d) { return new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss +zzzz").format(d); }
+ static String address(Address a) {return"("+quotify(a.description)+" NIL "+quotify(a.user)+" "+quotify(a.host)+")"; }
+ public static String addressList(Object a) {
+ if (a == null) return "NIL";
+ if (a instanceof Address) return "("+address((Address)a)+")";
+ Address[] aa = (Address[])a;
+ StringBuffer ret = new StringBuffer();
+ ret.append("(");
+ for(int i=0; i<aa.length; i++) { ret.append(aa[i]); if (i < aa.length - 1) ret.append(" "); }
+ ret.append(")");
+ return ret.toString();
+ }
+ static String flags(Mailbox.Iterator it) {
+ return
+ (it.deleted() ? "\\Deleted " : "") +
+ (it.seen() ? "\\Seen " : "") +
+ (it.flagged() ? "\\Flagged " : "") +
+ (it.draft() ? "\\Draft " : "") +
+ (it.answered() ? "\\Answered " : "") +
+ (it.recent() ? "\\Recent " : "");
+ }
+ static String envelope(Message m) {
+ return
+ "(" + quotify(m.arrival.toString()) +
+ " " + quotify(m.subject) +
+ " " + addressList(m.from) +
+ " " + addressList(m.headers.get("sender")) +
+ " " + addressList(m.replyto) +
+ " " + addressList(m.to) +
+ " " + addressList(m.cc) +
+ " " + addressList(m.bcc) +
+ " " + quotify((String)m.headers.get("in-reply-to")) +
+ " " + quotify(m.messageid) +
+ ")";
+ }
+
+ public static String qq(String s) {
+ StringBuffer ret = new StringBuffer(s.length() + 20);
+ ret.append('{');
+ ret.append(s.length());
+ ret.append('}');
+ ret.append('\r');
+ ret.append('\n');
+ ret.append(s);
+ ret.append('\r');
+ ret.append('\n');
+ return ret.toString();
+ }
+
+ private static String join(String delimit, String[] stuff) {
+ StringBuffer ret = new StringBuffer();
+ for(int i=0; i<stuff.length; i++) {
+ ret.append(stuff[i]);
+ if (i<stuff.length - 1) ret.append(delimit);
+ }
+ return ret.toString();
+ }
+
+
+ // Command Switchblock //////////////////////////////////////////////////////////////////////////////
+
+ private static final Hashtable commands = new Hashtable();
+ private static final int UID = 0; static { commands.put("UID", new Integer(UID)); }
+ private static final int AUTHENTICATE = 1; static { commands.put("AUTHENTICATE", new Integer(AUTHENTICATE)); }
+ private static final int LIST = 2; static { commands.put("LIST", new Integer(LIST)); }
+ private static final int LSUB = 3; static { commands.put("LSUB", new Integer(LSUB)); }
+ private static final int SUBSCRIBE = 4; static { commands.put("SUBSCRIBE", new Integer(SUBSCRIBE)); }
+ private static final int UNSUBSCRIBE = 5; static { commands.put("UNSUBSCRIBE", new Integer(UNSUBSCRIBE)); }
+ private static final int CAPABILITY = 6; static { commands.put("CAPABILITY", new Integer(CAPABILITY)); }
+ private static final int ID = 7; static { commands.put("ID", new Integer(ID)); }
+ private static final int LOGIN = 8; static { commands.put("LOGIN", new Integer(LOGIN)); }
+ private static final int LOGOUT = 9; static { commands.put("LOGOUT", new Integer(LOGOUT)); }
+ private static final int RENAME = 10; static { commands.put("RENAME", new Integer(RENAME)); }
+ private static final int EXAMINE = 11; static { commands.put("EXAMINE", new Integer(EXAMINE)); }
+ private static final int SELECT = 12; static { commands.put("SELECT", new Integer(SELECT)); }
+ private static final int COPY = 13; static { commands.put("COPY", new Integer(COPY)); }
+ private static final int DELETE = 14; static { commands.put("DELETE", new Integer(DELETE)); }
+ private static final int CHECK = 15; static { commands.put("CHECK", new Integer(CHECK)); }
+ private static final int NOOP = 16; static { commands.put("NOOP", new Integer(NOOP)); }
+ private static final int CLOSE = 17; static { commands.put("CLOSE", new Integer(CLOSE)); }
+ private static final int EXPUNGE = 18; static { commands.put("EXPUNGE", new Integer(EXPUNGE)); }
+ private static final int UNSELECT = 19; static { commands.put("UNSELECT", new Integer(UNSELECT)); }
+ private static final int CREATE = 20; static { commands.put("CREATE", new Integer(CREATE)); }
+ private static final int STATUS = 21; static { commands.put("STATUS", new Integer(STATUS)); }
+ private static final int FETCH = 22; static { commands.put("FETCH", new Integer(FETCH)); }
+ private static final int APPEND = 23; static { commands.put("APPEND", new Integer(APPEND)); }
+ private static final int STORE = 24; static { commands.put("STORE", new Integer(STORE)); }
+
+
+ // Main //////////////////////////////////////////////////////////////////////////////
+
+ /** simple listener for testing purposes */
+ public static void main(String[] args) throws Exception {
+ ServerSocket ss = new ServerSocket(143);
+ for(final Socket s = ss.accept();;)
+ new Thread() { public void run() { try {
+ final Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT+File.separatorChar+"imap", true);
+ new Session(s, root,
+ new Authenticator() {
+ public Mailbox authenticate(String u, String p) {
+ if (u.equals("megacz")&&p.equals("pass")) return root.slash("users",true).slash("megacz",true);
+ return null;
+ } } ).handleRequest();
+ } catch (Exception e) { e.printStackTrace(); } } }.start();
+ }