package org.ibex.mail.protocol;
import org.ibex.io.*;
+import org.ibex.crypto.*;
import org.ibex.jinetd.Listener;
import org.ibex.jinetd.Worker;
import org.ibex.mail.*;
public class IMAP {
public IMAP() { }
- public static final float version = (float)0.1;
+ public static final float version = (float)0.2;
// API Class //////////////////////////////////////////////////////////////////////////////
public void fetch(Query q, int spec, String[] headers, int start, int end, boolean uid);
public void lsub(String start, String ref);
public void list(String start, String ref);
- public static interface Authenticator { public abstract Mailbox authenticate(String user, String pass); }
public static class Exn extends MailException { public Exn(String s) { super(s); } }
public static class Bad extends Exn { public Bad(String s) { super(s); } }
public static class No extends Exn { public No(String s) { super(s); } }
Mailbox selected = null;
Mailbox root = null;
Mailbox selected() { if (selected == null) throw new Bad("no mailbox selected"); return selected; }
- final Server.Authenticator auth;
+ final Login auth;
final Client client;
- public MailboxWrapper(Server.Authenticator auth, Client c) { this.auth=auth; this.client=c;}
+ public MailboxWrapper(Login auth, Client c) { this.auth=auth; this.client=c;}
- private Mailbox mailbox(String name, boolean create) {
+ private Mailbox mailbox(String name, boolean create) { return mailbox(name, create, true); }
+ private Mailbox mailbox(String name, boolean create, boolean throwexn) {
if (name.equalsIgnoreCase("inbox")) return inbox;
Mailbox m = root;
for(StringTokenizer st = new StringTokenizer(name, sep + ""); st.hasMoreTokens();)
- if ((m = m.slash(st.nextToken(), create)) == null) throw new Server.No("no such mailbox " + name);
+ if ((m = m.slash(st.nextToken(), create)) == null) {
+ if (throwexn) throw new Server.No("no such mailbox " + name);
+ return null;
+ }
return m;
}
for(Mailbox.Iterator it=selected().iterator(q);it.next();) to.add(it.cur(), it.flags() | Mailbox.Flag.RECENT); }
public void login(String u, String p) {
- if ((root = auth.authenticate(u,p)) == null) throw new No("Login failed.");
+ Account account = null;
+ if ((account = auth.login(u,p)) == null) throw new No("Login failed.");
+ root = account.getMailbox(IMAP.class);
inbox = mailbox("INBOX", false); // FEATURE: ??
+ if (inbox == null) inbox = root;
}
public void unselect() { selected = null; }
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 create(String m) { mailbox(m, true, false); }
public void append(String m,int f,Date a,String b) { try {
mailbox(m,false).add(new Message(new Stream(b), new Message.Envelope(null,null,a)),f|Mailbox.Flag.RECENT);
} catch (Message.Malformed e) { throw new No(e.getMessage()); } }
String selectedName = null;
Mailbox inbox = null, root = null;
Server api;
+ Login auth = null;
Parser parser = null;
Connection conn = null;
- public Listener() { }
+ public Listener(Login auth) { this.auth = auth; }
Parser.Token token() { return parser.token(); }
void println(String s) { conn.println(s); }
void newline() { parser.newline(); }
public void handleRequest(Connection conn) {
this.conn = conn;
parser = new Parser(conn);
- api = new IMAP.MailboxWrapper(new Main.BogusAuthenticator(), this);
+ api = new IMAP.MailboxWrapper(auth, 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 {
if (!negate) {
if(e) for(int j=0; j<headers.length; j++) {
r.append(headers[j] + (j<headers.length-1?" ":""));
- if (m.headers.get(headers[j]) != null) payload += headers[j]+": "+m.headers.get(headers[j])+"\r\n";
+ if (m.headers.gets(headers[j]) != null) payload += headers[j]+": "+m.headers.gets(headers[j])+"\r\n";
}
} else {
throw new Server.No("HEADERS.NOT temporarily disaled");
if(e) { OUTER: for(Enumeration x=m.headers.keys(); x.hasMoreElements();) {
String key = (String)x.nextElement();
for(int j=0; j<headers.length; j++) if (key.equalsIgnoreCase(headers[j])) continue OUTER;
- payload += key + ": " + m.headers.get(key)+"\r\n";
+ payload += key + ": " + m.headers.gets(key)+"\r\n";
} }
*/
}
public static String addressList(Object a) {
if (a == null) return "NIL";
if (a instanceof Address) return "("+address((Address)a)+")";
+ if (a instanceof String) return "("+address(Address.parse((String)a))+")";
Address[] aa = (Address[])a;
StringBuffer ret = new StringBuffer();
ret.append("(");
"(" + quotify(m.envelope.arrival.toString()) +
" " + quotify(m.subject) +
" " + addressList(m.from) +
- " " + addressList(m.headers.get("sender")) +
+ " " + addressList(m.headers.gets("sender")) +
" " + addressList(m.replyto) +
" " + addressList(m.to) +
" " + addressList(m.cc) +
" " + addressList(m.bcc) +
- " " + quotify((String)m.headers.get("in-reply-to")) +
+ " " + quotify((String)m.headers.gets("in-reply-to")) +
" " + quotify(m.messageid) +
")";
}
// 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 Listener();
- } catch (Exception e) { e.printStackTrace(); } } }.start();
- }
- }
-
public static final int
PEEK=0x1, BODYSTRUCTURE=0x2, ENVELOPE=0x4, FLAGS=0x8, INTERNALDATE=0x10, FIELDS=0x800, FIELDSNOT=0x1000,
RFC822=0x20, RFC822TEXT=0x40, RFC822SIZE=0x80, HEADERNOT=0x100, UID=0x200, HEADER=0x400;
+
}