X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fmail%2Fprotocol%2FIMAP.java;h=346f007499530401afaf751f4ef82120fa4cc4e0;hb=c099a298576b1083c6be3259442900056032f0b1;hp=2291826b43ee58611776920d8d962a8021309a98;hpb=1a1f247c32e53cd4e776e5fb47c3c171bfd84fac;p=org.ibex.mail.git diff --git a/src/org/ibex/mail/protocol/IMAP.java b/src/org/ibex/mail/protocol/IMAP.java index 2291826..346f007 100644 --- a/src/org/ibex/mail/protocol/IMAP.java +++ b/src/org/ibex/mail/protocol/IMAP.java @@ -1,6 +1,7 @@ package org.ibex.mail.protocol; import org.ibex.io.*; import org.ibex.jinetd.Listener; +import org.ibex.jinetd.Worker; import org.ibex.net.*; import org.ibex.mail.*; import org.ibex.util.*; @@ -32,13 +33,7 @@ import java.io.*; // FEATURE: STARTTLS // FEATURE: asynchronous client notifications (need to re-read RFC) -public class IMAP implements Listener { - - public void accept(Connection c) { - Log.error(this, "IMAP got a connection!"); - new Listener().handleRequest(c); - c.close(); - } +public class IMAP { public IMAP() { } public static final float version = (float)0.1; @@ -163,7 +158,9 @@ public class IMAP implements Listener { public void delete(String m0) { delete(mailbox(m0,false)); } public void delete(Mailbox m) { if (!m.equals(inbox)) m.destroy(false); else throw new Bad("can't delete inbox"); } public void create(String m) { mailbox(m, true); } - public void append(String m,int f,Date a,String b){mailbox(m,false).add(new Message(null,null,b,a),f|Mailbox.Flag.RECENT);} + public void append(String m,int f,Date a,String b) { try { + mailbox(m,false).add(new Message(null,null,b,a),f|Mailbox.Flag.RECENT); + } catch (Message.Malformed e) { throw new No(e.getMessage()); } } public void check() { } public void noop() { } public void logout() { } @@ -213,7 +210,10 @@ public class IMAP implements Listener { } public void fetch(Query q, int spec, String[] headers, int start, int end, boolean uid) { for(Mailbox.Iterator it = selected().iterator(q); it.next(); ) { - client.fetch(it.num(), it.flags(), it.cur().size(), it.cur(), it.uid()); + Message message = ((spec & (BODYSTRUCTURE | ENVELOPE | INTERNALDATE | FIELDS | FIELDSNOT | RFC822 | + RFC822TEXT | RFC822SIZE | HEADERNOT | HEADER)) != 0) ? it.cur() : null; + int size = message == null ? 0 : message.size(); + client.fetch(it.num(), it.flags(), size, message, it.uid()); it.recent(false); } } @@ -235,13 +235,13 @@ public class IMAP implements Listener { void newline() { parser.newline(); } Query query() { return parser.query(); } public void handleRequest(Connection conn) { - parser = new Parser(conn); this.conn = conn; + parser = new Parser(conn); api = new IMAP.MailboxWrapper(new Main.BogusAuthenticator(), this); conn.setTimeout(30 * 60 * 1000); println("* OK " + conn.vhost + " " + IMAP.class.getName() + " IMAP4rev1 [RFC3501] v" + version + " server ready"); for(String tag = null;; newline()) try { - conn.out.flush(); + conn.flush(); boolean uid = false; tag = null; Parser.Token tok = token(); if (tok == null) return; tag = tok.astring(); String command = token().atom(); @@ -321,8 +321,8 @@ public class IMAP implements Listener { } println(tag+" OK "+command+" Completed. " + (commandKey == LOGIN ? ("[CAPABILITY "+Printer.join(" ", api.capability())+"]") : "")); - } catch (Server.Bad b) { println(tag==null ? "* BAD Invalid tag":(tag + " Bad " + b.toString())); b.printStackTrace(); - } catch (Server.No n) { println(tag==null?"* BAD Invalid tag":(tag+" No " + n.toString())); n.printStackTrace(); } + } 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 @@ -348,7 +348,7 @@ public class IMAP implements Listener { private void fetch(Object o, Parser.Token[] t, int num, int flags, int size, boolean uid, int muid) { Query q = o instanceof Query ? (Query)o : null; Message m = o instanceof Message ? (Message)o : null; - boolean e = m != null; + boolean e = q == null; lastfetch = t; int spec = 0; // spec; see constants for flags @@ -487,11 +487,9 @@ public class IMAP implements Listener { private static final int SEARCH = 25; static { commands.put("SEARCH", new Integer(SEARCH)); } } - public static class Parser extends Stream.In { + public static class Parser { private Stream stream; - public Parser(Stream from) { super(from.in); this.stream = from; } - public char peekc() { int i = read(); unread(((char)i)+""); return (char)i; } - public char getc() { return (char)read(); } + public Parser(Stream from) { this.stream = from; } public Token token(String s) { return new Token(s); } protected Query query() { String s = null; @@ -645,9 +643,9 @@ public class IMAP implements Listener { } public void newline() { - while (peekc() == '\r' || peekc() == '\n' || peekc() == ' ') { - for(char c = peekc(); c == ' ';) { getc(); c = peekc(); }; - for(char c = peekc(); c == '\r' || c == '\n';) { getc(); c = peekc(); }; + 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(); }; } } @@ -655,21 +653,21 @@ public class IMAP implements Listener { public Token token(boolean freak) { Vec toks = new Vec(); StringBuffer sb = new StringBuffer(); - char c = getc(); while (c == ' ') c = getc(); + char c = stream.getc(); while (c == ' ') c = stream.getc(); if (c == '\r' || c == '\n') { if (freak) bad("unexpected end of line"); return null; } else if (c == '{') { - while(peekc() != '}') sb.append(getc()); - stream.out.println("+ Ready when you are..."); + while(stream.peekc() != '}') sb.append(stream.getc()); + stream.println("+ Ready when you are..."); int octets = Integer.parseInt(sb.toString()); - while(peekc() == ' ') getc(); // whitespace - while (getc() != '\n' && getc() != '\r') { } + while(stream.peekc() == ' ') stream.getc(); // whitespace + while (stream.getc() != '\n' && stream.getc() != '\r') { } byte[] bytes = new byte[octets]; - read(bytes, 0, bytes.length); + stream.read(bytes, 0, bytes.length); return new Token(new String(bytes), true); } else if (c == '\"') { while(true) { - c = getc(); - if (c == '\\') sb.append(getc()); + c = stream.getc(); + if (c == '\\') sb.append(stream.getc()); else if (c == '\"') break; else sb.append(c); } @@ -686,11 +684,11 @@ public class IMAP implements Listener { } else while(true) { sb.append(c); - c = peekc(); + c = stream.peekc(); if (c == ' ' || c == '\"' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '\n' || c == '\r') return new Token(sb.toString(), false); - getc(); + stream.getc(); } } }