From b70cbb28b257c226e6e3edda780dc9aa71ada283 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 20 Apr 2014 19:31:28 +0000 Subject: [PATCH] * SusiMail: - Send CAPA - Pipeline STAT, UIDL, and LIST --- .../i2p/susi/webmail/pop3/POP3MailBox.java | 119 ++++++++++++++---- 1 file changed, 93 insertions(+), 26 deletions(-) diff --git a/apps/susimail/src/src/i2p/susi/webmail/pop3/POP3MailBox.java b/apps/susimail/src/src/i2p/susi/webmail/pop3/POP3MailBox.java index 74c46181c..a70c8bbec 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/pop3/POP3MailBox.java +++ b/apps/susimail/src/src/i2p/susi/webmail/pop3/POP3MailBox.java @@ -52,6 +52,8 @@ public class POP3MailBox { private boolean connected; private boolean supportsPipelining; + private boolean supportsTOP; + private boolean supportsUIDL; /** ID to size */ private final HashMap sizes; @@ -257,16 +259,35 @@ public class POP3MailBox { return connected; } + /** + * + * @param response line starting with +OK + */ + private void updateMailCount(String response) { + if (response == null || response.length() < 4) { + mails = 0; + return; + } + response = response.trim(); + try { + int i = response.indexOf(" ", 5); + mails = + Integer.parseInt( + i != -1 + ? response.substring(4, i) + : response.substring(4)); + } catch (NumberFormatException nfe) { + mails = 0; + } + } + /** * Caller must sync. * * @throws IOException */ - private void updateUIDLs() throws IOException - { + private void updateUIDLs(List lines) { uidlToID.clear(); - - List lines = sendCmdNl( "UIDL"); if (lines != null) { for (String line : lines) { int j = line.indexOf( " " ); @@ -292,12 +313,11 @@ public class POP3MailBox { * * @throws IOException */ - private void updateSizes() throws IOException { + private void updateSizes(List lines) { /* * try LIST */ sizes.clear(); - List lines = sendCmdNl("LIST"); if (lines != null) { for (String line : lines) { int j = line.indexOf(" "); @@ -363,27 +383,37 @@ public class POP3MailBox { try { // pipeline 2 commands lastError = ""; - List cmds = new ArrayList(3); - // TODO APOP (unsupported by postman) - cmds.add(new SendRecv(null, Mode.A1)); - // TODO CAPA - cmds.add(new SendRecv("USER " + user, Mode.A1)); - cmds.add(new SendRecv("PASS " + pass, Mode.A1)); - // We can't pipleline the STAT because we must - // enter the transaction state first. - //cmds.add("STAT"); - // wait for 3 +OK lines since the connect generates one - if (sendCmds(cmds) && sendCmd1a("STAT")) { - int i = lastLine.indexOf(" ", 5); - mails = - Integer.parseInt( - i != -1 - ? lastLine.substring(4, i) - : lastLine.substring(4)); - + boolean ok = doHandshake(); + if (ok) { + // TODO APOP (unsupported by postman) + List cmds = new ArrayList(4); + cmds.add(new SendRecv("USER " + user, Mode.A1)); + cmds.add(new SendRecv("PASS " + pass, Mode.A1)); + ok = sendCmds(cmds); + } + if (ok) { connected = true; - updateUIDLs(); - updateSizes(); + List cmds = new ArrayList(4); + SendRecv stat = new SendRecv("STAT", Mode.A1); + cmds.add(stat); + SendRecv uidl = new SendRecv("UIDL", Mode.LS); + cmds.add(uidl); + SendRecv list = new SendRecv("LIST", Mode.LS); + cmds.add(list); + // check individual responses + sendCmds(cmds); + if (stat.result) + updateMailCount(stat.response); + else + Debug.debug(Debug.DEBUG, "STAT failed"); + if (uidl.result) + updateUIDLs(uidl.ls); + else + Debug.debug(Debug.DEBUG, "UIDL failed"); + if (list.result) + updateSizes(list.ls); + else + Debug.debug(Debug.DEBUG, "LIST failed"); } else { if (lastError.equals("")) lastError = _("Error connecting to server"); @@ -398,6 +428,43 @@ public class POP3MailBox { } } } + + /** + * Check the initial response, send CAPA, check the CAPA result + * Caller must sync. + * + * @return true if successful + * @throws IOException + * @since 0.9.13 + */ + private boolean doHandshake() throws IOException { + // can we always pipeline this ? + supportsPipelining = false; + supportsUIDL = false; + supportsTOP = false; + List cmds = new ArrayList(2); + cmds.add(new SendRecv(null, Mode.A1)); + SendRecv capa = new SendRecv("CAPA", Mode.LS); + cmds.add(capa); + boolean rv = sendCmds(cmds); + if (rv) { + if (capa.ls != null) { + for (String cap : capa.ls) { + String t = cap.trim(); + if (t.equals("PIPELINING")) + supportsPipelining = true; + else if (t.equals("UIDL")) + supportsUIDL = true; + else if (t.equals("TOP")) + supportsTOP = true; + } + } + } + Debug.debug(Debug.DEBUG, "POP3 server caps: pipelining? " + supportsPipelining + + " UIDL? " + supportsUIDL + + " TOP? " + supportsTOP); + return rv; + } /** * send command to pop3 server (and expect single line answer)