* SusiMail:

- Send CAPA
   - Pipeline STAT, UIDL, and LIST
This commit is contained in:
zzz
2014-04-20 19:31:28 +00:00
parent 673c14287a
commit b70cbb28b2

View File

@@ -52,6 +52,8 @@ public class POP3MailBox {
private boolean connected; private boolean connected;
private boolean supportsPipelining; private boolean supportsPipelining;
private boolean supportsTOP;
private boolean supportsUIDL;
/** ID to size */ /** ID to size */
private final HashMap<Integer, Integer> sizes; private final HashMap<Integer, Integer> sizes;
@@ -257,16 +259,35 @@ public class POP3MailBox {
return connected; 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. * Caller must sync.
* *
* @throws IOException * @throws IOException
*/ */
private void updateUIDLs() throws IOException private void updateUIDLs(List<String> lines) {
{
uidlToID.clear(); uidlToID.clear();
List<String> lines = sendCmdNl( "UIDL");
if (lines != null) { if (lines != null) {
for (String line : lines) { for (String line : lines) {
int j = line.indexOf( " " ); int j = line.indexOf( " " );
@@ -292,12 +313,11 @@ public class POP3MailBox {
* *
* @throws IOException * @throws IOException
*/ */
private void updateSizes() throws IOException { private void updateSizes(List<String> lines) {
/* /*
* try LIST * try LIST
*/ */
sizes.clear(); sizes.clear();
List<String> lines = sendCmdNl("LIST");
if (lines != null) { if (lines != null) {
for (String line : lines) { for (String line : lines) {
int j = line.indexOf(" "); int j = line.indexOf(" ");
@@ -363,27 +383,37 @@ public class POP3MailBox {
try { try {
// pipeline 2 commands // pipeline 2 commands
lastError = ""; lastError = "";
List<SendRecv> cmds = new ArrayList<SendRecv>(3); boolean ok = doHandshake();
if (ok) {
// TODO APOP (unsupported by postman) // TODO APOP (unsupported by postman)
cmds.add(new SendRecv(null, Mode.A1)); List<SendRecv> cmds = new ArrayList<SendRecv>(4);
// TODO CAPA
cmds.add(new SendRecv("USER " + user, Mode.A1)); cmds.add(new SendRecv("USER " + user, Mode.A1));
cmds.add(new SendRecv("PASS " + pass, Mode.A1)); cmds.add(new SendRecv("PASS " + pass, Mode.A1));
// We can't pipleline the STAT because we must ok = sendCmds(cmds);
// enter the transaction state first. }
//cmds.add("STAT"); if (ok) {
// 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));
connected = true; connected = true;
updateUIDLs(); List<SendRecv> cmds = new ArrayList<SendRecv>(4);
updateSizes(); 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 { } else {
if (lastError.equals("")) if (lastError.equals(""))
lastError = _("Error connecting to server"); lastError = _("Error connecting to server");
@@ -399,6 +429,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<SendRecv> cmds = new ArrayList<SendRecv>(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) * send command to pop3 server (and expect single line answer)
* Response will be in lastLine. Does not read past the first line of the response. * Response will be in lastLine. Does not read past the first line of the response.