Methods Summary |
---|
public void | append(java.lang.String mbox, javax.mail.Flags f, java.util.Date d, com.sun.mail.iap.Literal data)APPEND Command.
appenduid(mbox, f, d, data, false); // ignore return value
|
public com.sun.mail.imap.AppendUID | appenduid(java.lang.String mbox, javax.mail.Flags f, java.util.Date d, com.sun.mail.iap.Literal data)APPEND Command, return uid from APPENDUID response code.
return appenduid(mbox, f, d, data, true);
|
public com.sun.mail.imap.AppendUID | appenduid(java.lang.String mbox, javax.mail.Flags f, java.util.Date d, com.sun.mail.iap.Literal data, boolean uid)
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
if (f != null) { // set Flags in appended message
// can't set the \Recent flag in APPEND
if (f.contains(Flags.Flag.RECENT)) {
f = new Flags(f); // copy, don't modify orig
f.remove(Flags.Flag.RECENT); // remove RECENT from copy
}
/*
* HACK ALERT: We want the flag_list to be written out
* without any checking/processing of the bytes in it. If
* I use writeString(), the flag_list will end up being
* quoted since it contains "illegal" characters. So I
* am depending on implementation knowledge that writeAtom()
* does not do any checking/processing - it just writes out
* the bytes. What we really need is a writeFoo() that just
* dumps out its argument.
*/
args.writeAtom(createFlagList(f));
}
if (d != null) // set INTERNALDATE in appended message
args.writeString(INTERNALDATE.format(d));
args.writeBytes(data);
Response[] r = command("APPEND", args);
// dispatch untagged responses
notifyResponseHandlers(r);
// Handle result of this command
handleResult(r[r.length-1]);
if (uid)
return getAppendUID(r[r.length-1]);
else
return null;
|
public synchronized void | authlogin(java.lang.String u, java.lang.String p)The AUTHENTICATE command with AUTH=LOGIN authenticate scheme
Vector v = new Vector();
String tag = null;
Response r = null;
boolean done = false;
try {
tag = writeCommand("AUTHENTICATE LOGIN", null);
} catch (Exception ex) {
// Convert this into a BYE response
r = Response.byeResponse(ex);
done = true;
}
OutputStream os = getOutputStream(); // stream to IMAP server
/* Wrap a BASE64Encoder around a ByteArrayOutputstream
* to craft b64 encoded username and password strings
*
* Note that the encoded bytes should be sent "as-is" to the
* server, *not* as literals or quoted-strings.
*
* Also note that unlike the B64 definition in MIME, CRLFs
* should *not* be inserted during the encoding process. So, I
* use Integer.MAX_VALUE (0x7fffffff (> 1G)) as the bytesPerLine,
* which should be sufficiently large !
*
* Finally, format the line in a buffer so it can be sent as
* a single packet, to avoid triggering a bug in SUN's SIMS 2.0
* server caused by patch 105346.
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStream b64os = new BASE64EncoderStream(bos, Integer.MAX_VALUE);
boolean first = true;
while (!done) { // loop till we are done
try {
r = readResponse();
if (r.isContinuation()) {
// Server challenge ..
String s;
if (first) { // Send encoded username
s = u;
first = false;
} else // Send encoded password
s = p;
// obtain b64 encoded bytes
b64os.write(ASCIIUtility.getBytes(s));
b64os.flush(); // complete the encoding
bos.write(CRLF); // CRLF termination
os.write(bos.toByteArray()); // write out line
os.flush(); // flush the stream
bos.reset(); // reset buffer
} else if (r.isTagged() && r.getTag().equals(tag))
// Ah, our tagged response
done = true;
else if (r.isBYE()) // outta here
done = true;
else // hmm .. unsolicited response here ?!
v.addElement(r);
} catch (Exception ioex) {
// convert this into a BYE response
r = Response.byeResponse(ioex);
done = true;
}
}
/* Dispatch untagged responses.
* NOTE: in our current upper level IMAP classes, we add the
* responseHandler to the Protocol object only *after* the
* connection has been authenticated. So, for now, the below
* code really ends up being just a no-op.
*/
Response[] responses = new Response[v.size()];
v.copyInto(responses);
notifyResponseHandlers(responses);
// Handle the final OK, NO, BAD or BYE response
handleResult(r);
// If the response includes a CAPABILITY response code, process it
setCapabilities(r);
// if we get this far without an exception, we're authenticated
authenticated = true;
|
public synchronized void | authplain(java.lang.String authzid, java.lang.String u, java.lang.String p)The AUTHENTICATE command with AUTH=PLAIN authentication scheme.
This is based heavly on the {@link #authlogin} method.
Vector v = new Vector();
String tag = null;
Response r = null;
boolean done = false;
try {
tag = writeCommand("AUTHENTICATE PLAIN", null);
} catch (Exception ex) {
// Convert this into a BYE response
r = Response.byeResponse(ex);
done = true;
}
OutputStream os = getOutputStream(); // stream to IMAP server
/* Wrap a BASE64Encoder around a ByteArrayOutputstream
* to craft b64 encoded username and password strings
*
* Note that the encoded bytes should be sent "as-is" to the
* server, *not* as literals or quoted-strings.
*
* Also note that unlike the B64 definition in MIME, CRLFs
* should *not* be inserted during the encoding process. So, I
* use Integer.MAX_VALUE (0x7fffffff (> 1G)) as the bytesPerLine,
* which should be sufficiently large !
*
* Finally, format the line in a buffer so it can be sent as
* a single packet, to avoid triggering a bug in SUN's SIMS 2.0
* server caused by patch 105346.
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStream b64os = new BASE64EncoderStream(bos, Integer.MAX_VALUE);
while (!done) { // loop till we are done
try {
r = readResponse();
if (r.isContinuation()) {
// Server challenge ..
final String nullByte = "\0";
String s = authzid + nullByte + u + nullByte + p;
// obtain b64 encoded bytes
b64os.write(ASCIIUtility.getBytes(s));
b64os.flush(); // complete the encoding
bos.write(CRLF); // CRLF termination
os.write(bos.toByteArray()); // write out line
os.flush(); // flush the stream
bos.reset(); // reset buffer
} else if (r.isTagged() && r.getTag().equals(tag))
// Ah, our tagged response
done = true;
else if (r.isBYE()) // outta here
done = true;
else // hmm .. unsolicited response here ?!
v.addElement(r);
} catch (Exception ioex) {
// convert this into a BYE response
r = Response.byeResponse(ioex);
done = true;
}
}
/* Dispatch untagged responses.
* NOTE: in our current upper level IMAP classes, we add the
* responseHandler to the Protocol object only *after* the
* connection has been authenticated. So, for now, the below
* code really ends up being just a no-op.
*/
Response[] responses = new Response[v.size()];
v.copyInto(responses);
notifyResponseHandlers(responses);
// Handle the final OK, NO, BAD or BYE response
handleResult(r);
// If the response includes a CAPABILITY response code, process it
setCapabilities(r);
// if we get this far without an exception, we're authenticated
authenticated = true;
|
public void | capability()CAPABILITY command.
// Check CAPABILITY
Response[] r = command("CAPABILITY", null);
if (!r[r.length-1].isOK())
throw new ProtocolException(r[r.length-1].toString());
capabilities = new HashMap(10);
authmechs = new ArrayList(5);
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
// Handle *all* untagged CAPABILITY responses.
// Though the spec seemingly states that only
// one CAPABILITY response string is allowed (6.1.1),
// some server vendors claim otherwise.
if (ir.keyEquals("CAPABILITY"))
parseCapabilities(ir);
}
|
public void | check()CHECK Command.
simpleCommand("CHECK", null);
|
public void | close()CLOSE Command.
simpleCommand("CLOSE", null);
|
public void | copy(com.sun.mail.imap.protocol.MessageSet[] msgsets, java.lang.String mbox)COPY command.
copy(MessageSet.toString(msgsets), mbox);
|
public void | copy(int start, int end, java.lang.String mbox)
copy(String.valueOf(start) + ":" + String.valueOf(end),
mbox);
|
private void | copy(java.lang.String msgSequence, java.lang.String mbox)
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeAtom(msgSequence);
args.writeString(mbox);
simpleCommand("COPY", args);
|
public void | create(java.lang.String mbox)CREATE Command.
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
simpleCommand("CREATE", args);
|
private java.lang.String | createFlagList(javax.mail.Flags flags)Creates an IMAP flag_list from the given Flags object.
StringBuffer sb = new StringBuffer();
sb.append("("); // start of flag_list
Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags
boolean first = true;
for (int i = 0; i < sf.length; i++) {
String s;
Flags.Flag f = sf[i];
if (f == Flags.Flag.ANSWERED)
s = "\\Answered";
else if (f == Flags.Flag.DELETED)
s = "\\Deleted";
else if (f == Flags.Flag.DRAFT)
s = "\\Draft";
else if (f == Flags.Flag.FLAGGED)
s = "\\Flagged";
else if (f == Flags.Flag.RECENT)
s = "\\Recent";
else if (f == Flags.Flag.SEEN)
s = "\\Seen";
else
continue; // skip it
if (first)
first = false;
else
sb.append(' ");
sb.append(s);
}
String[] uf = flags.getUserFlags(); // get the user flag strings
for (int i = 0; i < uf.length; i++) {
if (first)
first = false;
else
sb.append(' ");
sb.append(uf[i]);
}
sb.append(")"); // terminate flag_list
return sb.toString();
|
public void | delete(java.lang.String mbox)DELETE Command.
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
simpleCommand("DELETE", args);
|
public void | deleteACL(java.lang.String mbox, java.lang.String user)DELETEACL Command.
if (!hasCapability("ACL"))
throw new BadCommandException("ACL not supported");
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
args.writeString(user);
Response[] r = command("DELETEACL", args);
Response response = r[r.length-1];
// dispatch untagged responses
notifyResponseHandlers(r);
handleResult(response);
|
public void | disconnect()Close socket connection.
This method just makes the Protocol.disconnect() method
public.
super.disconnect();
authenticated = false; // just in case
|
private com.sun.mail.imap.protocol.ListInfo[] | doList(java.lang.String cmd, java.lang.String ref, java.lang.String pat)
// encode the mbox as per RFC2060
ref = BASE64MailboxEncoder.encode(ref);
pat = BASE64MailboxEncoder.encode(pat);
Argument args = new Argument();
args.writeString(ref);
args.writeString(pat);
Response[] r = command(cmd, args);
ListInfo[] linfo = null;
Response response = r[r.length-1];
if (response.isOK()) { // command succesful
Vector v = new Vector(1);
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals(cmd)) {
v.addElement(new ListInfo(ir));
r[i] = null;
}
}
if (v.size() > 0) {
linfo = new ListInfo[v.size()];
v.copyInto(linfo);
}
}
// Dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
return linfo;
|
public com.sun.mail.imap.protocol.MailboxInfo | examine(java.lang.String mbox)EXAMINE Command.
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
Response[] r = command("EXAMINE", args);
// Note that MailboxInfo also removes those responses
// it knows about
MailboxInfo minfo = new MailboxInfo(r);
minfo.mode = Folder.READ_ONLY; // Obviously
// dispatch any remaining untagged responses
notifyResponseHandlers(r);
handleResult(r[r.length-1]);
return minfo;
|
public void | expunge()EXPUNGE Command.
simpleCommand("EXPUNGE", null);
|
public com.sun.mail.iap.Response[] | fetch(com.sun.mail.imap.protocol.MessageSet[] msgsets, java.lang.String what)
return fetch(MessageSet.toString(msgsets), what, false);
|
public com.sun.mail.iap.Response[] | fetch(int start, int end, java.lang.String what)
return fetch(String.valueOf(start) + ":" + String.valueOf(end),
what, false);
|
public com.sun.mail.iap.Response[] | fetch(int msg, java.lang.String what)
return fetch(String.valueOf(msg), what, false);
|
private com.sun.mail.iap.Response[] | fetch(java.lang.String msgSequence, java.lang.String what, boolean uid)
if (uid)
return command("UID FETCH " + msgSequence +" (" + what + ")",null);
else
return command("FETCH " + msgSequence + " (" + what + ")", null);
|
public com.sun.mail.imap.protocol.BODY | fetchBody(int msgno, java.lang.String section)Fetch given BODY section.
return fetchBody(msgno, section, false);
|
protected com.sun.mail.imap.protocol.BODY | fetchBody(int msgno, java.lang.String section, boolean peek)
Response[] r;
if (peek)
r = fetch(msgno,
"BODY.PEEK[" + (section == null ? "]" : section + "]"));
else
r = fetch(msgno,
"BODY[" + (section == null ? "]" : section + "]"));
notifyResponseHandlers(r);
Response response = r[r.length-1];
if (response.isOK())
return (BODY)FetchResponse.getItem(r, msgno, BODY.class);
else if (response.isNO())
return null;
else {
handleResult(response);
return null;
}
|
public com.sun.mail.imap.protocol.BODY | fetchBody(int msgno, java.lang.String section, int start, int size)Partial FETCH of given BODY section.
return fetchBody(msgno, section, start, size, false, null);
|
public com.sun.mail.imap.protocol.BODY | fetchBody(int msgno, java.lang.String section, int start, int size, com.sun.mail.iap.ByteArray ba)Partial FETCH of given BODY section.
return fetchBody(msgno, section, start, size, false, ba);
|
protected com.sun.mail.imap.protocol.BODY | fetchBody(int msgno, java.lang.String section, int start, int size, boolean peek, com.sun.mail.iap.ByteArray ba)
this.ba = ba; // save for later use by getResponseBuffer
Response[] r = fetch(
msgno, (peek ? "BODY.PEEK[" : "BODY[" ) +
(section == null ? "]<" : (section +"]<")) +
String.valueOf(start) + "." +
String.valueOf(size) + ">"
);
notifyResponseHandlers(r);
Response response = r[r.length-1];
if (response.isOK())
return (BODY)FetchResponse.getItem(r, msgno, BODY.class);
else if (response.isNO())
return null;
else {
handleResult(response);
return null;
}
|
public com.sun.mail.imap.protocol.BODYSTRUCTURE | fetchBodyStructure(int msgno)Fetch the BODYSTRUCTURE of the specified message.
Response[] r = fetch(msgno, "BODYSTRUCTURE");
notifyResponseHandlers(r);
Response response = r[r.length-1];
if (response.isOK())
return (BODYSTRUCTURE)FetchResponse.getItem(r, msgno,
BODYSTRUCTURE.class);
else if (response.isNO())
return null;
else {
handleResult(response);
return null;
}
|
public javax.mail.Flags | fetchFlags(int msgno)Fetch the FLAGS for the given message.
Flags flags = null;
Response[] r = fetch(msgno, "FLAGS");
// Search for our FLAGS response
for (int i = 0, len = r.length; i < len; i++) {
if (r[i] == null ||
!(r[i] instanceof FetchResponse) ||
((FetchResponse)r[i]).getNumber() != msgno)
continue;
FetchResponse fr = (FetchResponse)r[i];
if ((flags = (Flags)fr.getItem(Flags.class)) != null) {
r[i] = null; // remove this response
break;
}
}
// dispatch untagged responses
notifyResponseHandlers(r);
handleResult(r[r.length-1]);
return flags;
|
public com.sun.mail.imap.protocol.RFC822DATA | fetchRFC822(int msgno, java.lang.String what)Fetch the specified RFC822 Data item. 'what' names
the item to be fetched. 'what' can be null
to fetch the whole message.
Response[] r = fetch(msgno,
what == null ? "RFC822" : "RFC822." + what
);
// dispatch untagged responses
notifyResponseHandlers(r);
Response response = r[r.length-1];
if (response.isOK())
return (RFC822DATA)FetchResponse.getItem(r, msgno,
RFC822DATA.class);
else if (response.isNO())
return null;
else {
handleResult(response);
return null;
}
|
public com.sun.mail.imap.protocol.UID | fetchSequenceNumber(long uid)Get the sequence number for the given UID. A UID object
containing the sequence number is returned. If the given UID
is invalid, null is returned.
UID u = null;
Response[] r = fetch(String.valueOf(uid), "UID", true);
for (int i = 0, len = r.length; i < len; i++) {
if (r[i] == null || !(r[i] instanceof FetchResponse))
continue;
FetchResponse fr = (FetchResponse)r[i];
if ((u = (UID)fr.getItem(UID.class)) != null) {
if (u.uid == uid) // this is the one we want
break;
else
u = null;
}
}
notifyResponseHandlers(r);
handleResult(r[r.length-1]);
return u;
|
public com.sun.mail.imap.protocol.UID[] | fetchSequenceNumbers(long start, long end)Get the sequence numbers for UIDs ranging from start till end.
UID objects that contain the sequence numbers are returned.
If no UIDs in the given range are found, an empty array is returned.
Response[] r = fetch(String.valueOf(start) + ":" +
(end == UIDFolder.LASTUID ? "*" :
String.valueOf(end)),
"UID", true);
UID u;
Vector v = new Vector();
for (int i = 0, len = r.length; i < len; i++) {
if (r[i] == null || !(r[i] instanceof FetchResponse))
continue;
FetchResponse fr = (FetchResponse)r[i];
if ((u = (UID)fr.getItem(UID.class)) != null)
v.addElement(u);
}
notifyResponseHandlers(r);
handleResult(r[r.length-1]);
UID[] ua = new UID[v.size()];
v.copyInto(ua);
return ua;
|
public com.sun.mail.imap.protocol.UID[] | fetchSequenceNumbers(long[] uids)Get the sequence numbers for UIDs ranging from start till end.
UID objects that contain the sequence numbers are returned.
If no UIDs in the given range are found, an empty array is returned.
StringBuffer sb = new StringBuffer();
for (int i = 0; i < uids.length; i++) {
if (i > 0)
sb.append(",");
sb.append(String.valueOf(uids[i]));
}
Response[] r = fetch(sb.toString(), "UID", true);
UID u;
Vector v = new Vector();
for (int i = 0, len = r.length; i < len; i++) {
if (r[i] == null || !(r[i] instanceof FetchResponse))
continue;
FetchResponse fr = (FetchResponse)r[i];
if ((u = (UID)fr.getItem(UID.class)) != null)
v.addElement(u);
}
notifyResponseHandlers(r);
handleResult(r[r.length-1]);
UID[] ua = new UID[v.size()];
v.copyInto(ua);
return ua;
|
public com.sun.mail.imap.protocol.UID | fetchUID(int msgno)Fetch the IMAP UID for the given message.
Response[] r = fetch(msgno, "UID");
// dispatch untagged responses
notifyResponseHandlers(r);
Response response = r[r.length-1];
if (response.isOK())
return (UID)FetchResponse.getItem(r, msgno, UID.class);
else if (response.isNO()) // XXX: Issue NOOP ?
return null;
else {
handleResult(response);
return null; // NOTREACHED
}
|
public com.sun.mail.imap.ACL[] | getACL(java.lang.String mbox)GETACL Command.
if (!hasCapability("ACL"))
throw new BadCommandException("ACL not supported");
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
Response[] r = command("GETACL", args);
Response response = r[r.length-1];
// Grab all ACL responses
Vector v = new Vector();
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("ACL")) {
// acl_data ::= "ACL" SPACE mailbox
// *(SPACE identifier SPACE rights)
// read name of mailbox and throw away
ir.readAtomString();
String name = null;
while ((name = ir.readAtomString()) != null) {
String rights = ir.readAtomString();
if (rights == null)
break;
ACL acl = new ACL(name, new Rights(rights));
v.addElement(acl);
}
r[i] = null;
}
}
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
ACL[] aa = new ACL[v.size()];
v.copyInto(aa);
return aa;
|
private com.sun.mail.imap.AppendUID | getAppendUID(com.sun.mail.iap.Response r)If the response contains an APPENDUID response code, extract
it and return an AppendUID object with the information.
if (!r.isOK())
return null;
byte b;
while ((b = r.readByte()) > 0 && b != (byte)'[")
;
if (b == 0)
return null;
String s;
s = r.readAtom();
if (!s.equalsIgnoreCase("APPENDUID"))
return null;
long uidvalidity = r.readLong();
long uid = r.readLong();
return new AppendUID(uidvalidity, uid);
|
public java.util.Map | getCapabilities()Return the map of capabilities returned by the server.
return capabilities;
|
java.io.OutputStream | getIMAPOutputStream()
return getOutputStream();
|
public javax.mail.Quota[] | getQuota(java.lang.String root)GETQUOTA Command.
Returns an array of Quota objects, representing the quotas
for this quotaroot.
if (!hasCapability("QUOTA"))
throw new BadCommandException("QUOTA not supported");
Argument args = new Argument();
args.writeString(root);
Response[] r = command("GETQUOTA", args);
Quota quota = null;
Vector v = new Vector();
Response response = r[r.length-1];
// Grab all QUOTA responses
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("QUOTA")) {
quota = parseQuota(ir);
v.addElement(quota);
r[i] = null;
}
}
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
Quota[] qa = new Quota[v.size()];
v.copyInto(qa);
return qa;
|
public javax.mail.Quota[] | getQuotaRoot(java.lang.String mbox)GETQUOTAROOT Command.
Returns an array of Quota objects, representing the quotas
for this mailbox and, indirectly, the quotaroots for this
mailbox.
if (!hasCapability("QUOTA"))
throw new BadCommandException("GETQUOTAROOT not supported");
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
Response[] r = command("GETQUOTAROOT", args);
Response response = r[r.length-1];
Hashtable tab = new Hashtable();
// Grab all QUOTAROOT and QUOTA responses
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("QUOTAROOT")) {
// quotaroot_response
// ::= "QUOTAROOT" SP astring *(SP astring)
// read name of mailbox and throw away
ir.readAtomString();
// for each quotaroot add a placeholder quota
String root = null;
while ((root = ir.readAtomString()) != null)
tab.put(root, new Quota(root));
r[i] = null;
} else if (ir.keyEquals("QUOTA")) {
Quota quota = parseQuota(ir);
Quota q = (Quota)tab.get(quota.quotaRoot);
if (q != null && q.resources != null) {
// XXX - should merge resources
}
tab.put(quota.quotaRoot, quota);
r[i] = null;
}
}
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
Quota[] qa = new Quota[tab.size()];
Enumeration e = tab.elements();
for (int i = 0; e.hasMoreElements(); i++)
qa[i] = (Quota)e.nextElement();
return qa;
|
protected com.sun.mail.iap.ByteArray | getResponseBuffer()Return a buffer to read a response into.
The buffer is provided by fetchBody and is
used only once.
ByteArray ret = ba;
ba = null;
return ret;
|
public boolean | hasCapability(java.lang.String c)Check whether the given capability is supported by
this server. Returns true if so, otherwise
returns false.
return capabilities.containsKey(c.toUpperCase(Locale.ENGLISH));
|
public void | idleAbort()Abort an IDLE command. While one thread is blocked in
readIdleResponse(), another thread will use this method
to abort the IDLE command, which will cause the server
to send the closing tag for the IDLE command, which
readIdleResponse() and processIdleResponse() will see
and terminate the IDLE state.
OutputStream os = getOutputStream();
try {
os.write(DONE);
os.flush();
} catch (IOException ex) {
// nothing to do, hope to detect it again later
}
|
public synchronized void | idleStart()IDLE Command.
If the server supports the IDLE command extension, the IDLE
command is issued and this method blocks until a response has
been received. Once the first response has been received, the
IDLE command is terminated and all responses are collected and
handled and this method returns.
Note that while this method is blocked waiting for a response,
no other threads may issue any commands to the server that would
use this same connection.
if (!hasCapability("IDLE"))
throw new BadCommandException("IDLE not supported");
Response r;
// write the command
try {
idleTag = writeCommand("IDLE", null);
r = readResponse();
} catch (LiteralException lex) {
r = lex.getResponse();
} catch (Exception ex) {
// Convert this into a BYE response
r = Response.byeResponse(ex);
}
if (!r.isContinuation())
handleResult(r);
|
public boolean | isAuthenticated()Returns true if the connection has been authenticated,
either due to a successful login, or due to a PREAUTH greeting response.
return authenticated;
|
public boolean | isREV1()Returns true if this is a IMAP4rev1 server
return rev1;
|
private int[] | issueSearch(java.lang.String msgSequence, javax.mail.search.SearchTerm term, java.lang.String charset)
// Generate a search-sequence with the given charset
Argument args = SearchSequence.generateSequence(term,
charset == null ? null :
MimeUtility.javaCharset(charset)
);
args.writeAtom(msgSequence);
Response[] r;
if (charset == null) // text is all US-ASCII
r = command("SEARCH", args);
else
r = command("SEARCH CHARSET " + charset, args);
Response response = r[r.length-1];
int[] matches = null;
// Grab all SEARCH responses
if (response.isOK()) { // command succesful
Vector v = new Vector();
int num;
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
// There *will* be one SEARCH response.
if (ir.keyEquals("SEARCH")) {
while ((num = ir.readNumber()) != -1)
v.addElement(new Integer(num));
r[i] = null;
}
}
// Copy the vector into 'matches'
int vsize = v.size();
matches = new int[vsize];
for (int i = 0; i < vsize; i++)
matches[i] = ((Integer)v.elementAt(i)).intValue();
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
return matches;
|
public com.sun.mail.imap.protocol.ListInfo[] | list(java.lang.String ref, java.lang.String pattern)LIST Command.
return doList("LIST", ref, pattern);
|
public com.sun.mail.imap.Rights[] | listRights(java.lang.String mbox, java.lang.String user)LISTRIGHTS Command.
if (!hasCapability("ACL"))
throw new BadCommandException("ACL not supported");
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
args.writeString(user);
Response[] r = command("LISTRIGHTS", args);
Response response = r[r.length-1];
// Grab LISTRIGHTS response
Vector v = new Vector();
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("LISTRIGHTS")) {
// listrights_data ::= "LISTRIGHTS" SPACE mailbox
// SPACE identifier SPACE rights *(SPACE rights)
// read name of mailbox and throw away
ir.readAtomString();
// read identifier and throw away
ir.readAtomString();
String rights;
while ((rights = ir.readAtomString()) != null)
v.addElement(new Rights(rights));
r[i] = null;
}
}
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
Rights[] ra = new Rights[v.size()];
v.copyInto(ra);
return ra;
|
public void | login(java.lang.String u, java.lang.String p)LOGIN Command.
Argument args = new Argument();
args.writeString(u);
args.writeString(p);
Response[] r = command("LOGIN", args);
// dispatch untagged responses
notifyResponseHandlers(r);
// Handle result of this command
handleResult(r[r.length-1]);
// If the response includes a CAPABILITY response code, process it
setCapabilities(r[r.length-1]);
// if we get this far without an exception, we're authenticated
authenticated = true;
|
public void | logout()LOGOUT Command.
// XXX - what happens if exception is thrown?
Response[] r = command("LOGOUT", null);
authenticated = false;
// dispatch any unsolicited responses.
// NOTE that the BYE response is dispatched here as well
notifyResponseHandlers(r);
disconnect();
|
public com.sun.mail.imap.protocol.ListInfo[] | lsub(java.lang.String ref, java.lang.String pattern)LSUB Command.
return doList("LSUB", ref, pattern);
|
public com.sun.mail.imap.Rights | myRights(java.lang.String mbox)MYRIGHTS Command.
if (!hasCapability("ACL"))
throw new BadCommandException("ACL not supported");
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
Response[] r = command("MYRIGHTS", args);
Response response = r[r.length-1];
// Grab MYRIGHTS response
Rights rights = null;
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("MYRIGHTS")) {
// myrights_data ::= "MYRIGHTS" SPACE mailbox SPACE rights
// read name of mailbox and throw away
ir.readAtomString();
String rs = ir.readAtomString();
if (rights == null)
rights = new Rights(rs);
r[i] = null;
}
}
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
return rights;
|
public com.sun.mail.imap.protocol.Namespaces | namespace()NAMESPACE Command.
if (!hasCapability("NAMESPACE"))
throw new BadCommandException("NAMESPACE not supported");
Response[] r = command("NAMESPACE", null);
Namespaces namespace = null;
Response response = r[r.length-1];
// Grab NAMESPACE response
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("NAMESPACE")) {
if (namespace == null)
namespace = new Namespaces(ir);
r[i] = null;
}
}
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
return namespace;
|
public void | noop()The NOOP command.
if (debug)
out.println("IMAP DEBUG: IMAPProtocol noop");
simpleCommand("NOOP", null);
|
protected void | parseCapabilities(com.sun.mail.iap.Response r)Parse the capabilities from a CAPABILITY response or from
a CAPABILITY response code attached to (e.g.) an OK response.
String s;
while ((s = r.readAtom(']")) != null) {
if (s.length() == 0) {
if (r.peekByte() == (byte)']")
break;
/*
* Probably found something here that's not an atom.
* Rather than loop forever or fail completely, we'll
* try to skip this bogus capability. This is known
* to happen with:
* Netscape Messaging Server 4.03 (built Apr 27 1999)
* that returns:
* * CAPABILITY * CAPABILITY IMAP4 IMAP4rev1 ...
* The "*" in the middle of the capability list causes
* us to loop forever here.
*/
r.skipToken();
} else {
capabilities.put(s.toUpperCase(Locale.ENGLISH), s);
if (s.regionMatches(true, 0, "AUTH=", 0, 5)) {
authmechs.add(s.substring(5));
if (debug)
out.println("IMAP DEBUG: AUTH: " + s.substring(5));
}
}
}
|
private javax.mail.Quota | parseQuota(com.sun.mail.iap.Response r)Parse a QUOTA response.
// quota_response ::= "QUOTA" SP astring SP quota_list
String quotaRoot = r.readAtomString(); // quotaroot ::= astring
Quota q = new Quota(quotaRoot);
r.skipSpaces();
// quota_list ::= "(" #quota_resource ")"
if (r.readByte() != '(")
throw new ParsingException("parse error in QUOTA");
Vector v = new Vector();
while (r.peekByte() != ')") {
// quota_resource ::= atom SP number SP number
String name = r.readAtom();
if (name != null) {
long usage = r.readLong();
long limit = r.readLong();
Quota.Resource res = new Quota.Resource(name, usage, limit);
v.addElement(res);
}
}
r.readByte();
q.resources = new Quota.Resource[v.size()];
v.copyInto(q.resources);
return q;
|
public com.sun.mail.imap.protocol.BODY | peekBody(int msgno, java.lang.String section)Fetch given BODY section, without marking the message
as SEEN.
return fetchBody(msgno, section, true);
|
public com.sun.mail.imap.protocol.BODY | peekBody(int msgno, java.lang.String section, int start, int size)Partial FETCH of given BODY section, without setting SEEN flag.
return fetchBody(msgno, section, start, size, true, null);
|
public com.sun.mail.imap.protocol.BODY | peekBody(int msgno, java.lang.String section, int start, int size, com.sun.mail.iap.ByteArray ba)Partial FETCH of given BODY section, without setting SEEN flag.
return fetchBody(msgno, section, start, size, true, ba);
|
protected void | processGreeting(com.sun.mail.iap.Response r)Check the greeting when first connecting; look for PREAUTH response.
super.processGreeting(r); // check if it's BAD
if (r.isOK()) { // check if it's OK
setCapabilities(r);
return;
}
// only other choice is PREAUTH
IMAPResponse ir = (IMAPResponse)r;
if (ir.keyEquals("PREAUTH")) {
authenticated = true;
setCapabilities(r);
} else
throw new ConnectionException(this, r);
|
public boolean | processIdleResponse(com.sun.mail.iap.Response r)Process a response returned by readIdleResponse().
This method will be called with appropriate locks
held so that the processing of the response is safe.
Response[] responses = new Response[1];
responses[0] = r;
boolean done = false; // done reading responses?
notifyResponseHandlers(responses);
if (r.isBYE()) // shouldn't wait for command completion response
done = true;
// If this is a matching command completion response, we are done
if (r.isTagged() && r.getTag().equals(idleTag))
done = true;
if (done)
idleTag = null; // no longer in IDLE
handleResult(r);
return !done;
|
public void | proxyauth(java.lang.String u)PROXYAUTH Command.
Argument args = new Argument();
args.writeString(u);
simpleCommand("PROXYAUTH", args);
|
public synchronized com.sun.mail.iap.Response | readIdleResponse()While an IDLE command is in progress, read a response
sent from the server. The response is read with no locks
held so that when the read blocks waiting for the response
from the server it's not holding locks that would prevent
other threads from interrupting the IDLE command.
if (idleTag == null)
return null; // IDLE not in progress
Response r;
try {
r = readResponse();
} catch (IOException ioex) {
// convert this into a BYE response
r = Response.byeResponse(ioex);
} catch (ProtocolException pex) {
// convert this into a BYE response
r = Response.byeResponse(pex);
}
return r;
|
public com.sun.mail.iap.Response | readResponse()Read a response from the server.
// assert Thread.holdsLock(this);
// can't assert because it's called from constructor
return IMAPResponse.readResponse(this);
|
public void | rename(java.lang.String o, java.lang.String n)RENAME Command.
// encode the mbox as per RFC2060
o = BASE64MailboxEncoder.encode(o);
n = BASE64MailboxEncoder.encode(n);
Argument args = new Argument();
args.writeString(o);
args.writeString(n);
simpleCommand("RENAME", args);
|
public void | sasllogin(java.lang.String[] allowed, java.lang.String realm, java.lang.String authzid, java.lang.String u, java.lang.String p)SASL-based login.
if (saslAuthenticator == null) {
try {
Class sac = Class.forName(
"com.sun.mail.imap.protocol.IMAPSaslAuthenticator");
Constructor c = sac.getConstructor(new Class[] {
IMAPProtocol.class,
String.class,
Properties.class,
Boolean.TYPE,
PrintStream.class,
String.class
});
saslAuthenticator = (SaslAuthenticator)c.newInstance(
new Object[] {
this,
name,
props,
debug ? Boolean.TRUE : Boolean.FALSE,
out,
host
});
} catch (Exception ex) {
if (debug)
out.println("IMAP DEBUG: Can't load SASL authenticator: " +
ex);
// probably because we're running on a system without SASL
return; // not authenticated, try without SASL
}
}
// were any allowed mechanisms specified?
List v;
if (allowed != null && allowed.length > 0) {
// remove anything not supported by the server
v = new ArrayList(allowed.length);
for (int i = 0; i < allowed.length; i++)
if (authmechs.contains(allowed[i])) // XXX - case must match
v.add(allowed[i]);
} else {
// everything is allowed
v = authmechs;
}
String[] mechs = (String[])v.toArray(new String[v.size()]);
if (saslAuthenticator.authenticate(mechs, realm, authzid, u, p))
authenticated = true;
|
public int[] | search(com.sun.mail.imap.protocol.MessageSet[] msgsets, javax.mail.search.SearchTerm term)Issue the given search criterion on the specified message sets.
Returns array of matching sequence numbers. An empty array
is returned if no matches are found.
return search(MessageSet.toString(msgsets), term);
|
public int[] | search(javax.mail.search.SearchTerm term)Issue the given search criterion on all messages in this folder.
Returns array of matching sequence numbers. An empty array
is returned if no matches are found.
return search("ALL", term);
|
private int[] | search(java.lang.String msgSequence, javax.mail.search.SearchTerm term)
// Check if the search "text" terms contain only ASCII chars
if (SearchSequence.isAscii(term)) {
try {
return issueSearch(msgSequence, term, null);
} catch (IOException ioex) { /* will not happen */ }
}
/* The search "text" terms do contain non-ASCII chars. We need to
* use SEARCH CHARSET <charset> ...
* The charsets we try to use are UTF-8 and the locale's
* default charset. If the server supports UTF-8, great,
* always use it. Else we try to use the default charset.
*/
// Cycle thru the list of charsets
for (int i = 0; i < searchCharsets.length; i++) {
if (searchCharsets[i] == null)
continue;
try {
return issueSearch(msgSequence, term, searchCharsets[i]);
} catch (CommandFailedException cfx) {
/* Server returned NO. For now, I'll just assume that
* this indicates that this charset is unsupported.
* We can check the BADCHARSET response code once
* that's spec'd into the IMAP RFC ..
*/
searchCharsets[i] = null;
continue;
} catch (IOException ioex) {
/* Charset conversion failed. Try the next one */
continue;
} catch (ProtocolException pex) {
throw pex;
} catch (SearchException sex) {
throw sex;
}
}
// No luck.
throw new SearchException("Search failed");
|
public com.sun.mail.imap.protocol.MailboxInfo | select(java.lang.String mbox)SELECT Command.
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
Response[] r = command("SELECT", args);
// Note that MailboxInfo also removes those responses
// it knows about
MailboxInfo minfo = new MailboxInfo(r);
// dispatch any remaining untagged responses
notifyResponseHandlers(r);
Response response = r[r.length-1];
if (response.isOK()) { // command succesful
if (response.toString().indexOf("READ-ONLY") != -1)
minfo.mode = Folder.READ_ONLY;
else
minfo.mode = Folder.READ_WRITE;
}
handleResult(response);
return minfo;
|
public void | setACL(java.lang.String mbox, char modifier, com.sun.mail.imap.ACL acl)SETACL Command.
if (!hasCapability("ACL"))
throw new BadCommandException("ACL not supported");
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
args.writeString(acl.getName());
String rights = acl.getRights().toString();
if (modifier == '+" || modifier == '-")
rights = modifier + rights;
args.writeString(rights);
Response[] r = command("SETACL", args);
Response response = r[r.length-1];
// dispatch untagged responses
notifyResponseHandlers(r);
handleResult(response);
|
protected void | setCapabilities(com.sun.mail.iap.Response r)If the response contains a CAPABILITY response code, extract
it and save the capabilities.
byte b;
while ((b = r.readByte()) > 0 && b != (byte)'[")
;
if (b == 0)
return;
String s;
s = r.readAtom();
if (!s.equalsIgnoreCase("CAPABILITY"))
return;
capabilities = new HashMap(10);
authmechs = new ArrayList(5);
parseCapabilities(r);
|
public void | setQuota(javax.mail.Quota quota)SETQUOTA Command.
Set the indicated quota on the corresponding quotaroot.
if (!hasCapability("QUOTA"))
throw new BadCommandException("QUOTA not supported");
Argument args = new Argument();
args.writeString(quota.quotaRoot);
Argument qargs = new Argument();
if (quota.resources != null) {
for (int i = 0; i < quota.resources.length; i++) {
qargs.writeAtom(quota.resources[i].name);
qargs.writeNumber(quota.resources[i].limit);
}
}
args.writeArgument(qargs);
Response[] r = command("SETQUOTA", args);
Response response = r[r.length-1];
// XXX - It's not clear from the RFC whether the SETQUOTA command
// will provoke untagged QUOTA responses. If it does, perhaps
// we should grab them here and return them?
/*
Quota quota = null;
Vector v = new Vector();
// Grab all QUOTA responses
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("QUOTA")) {
quota = parseQuota(ir);
v.addElement(quota);
r[i] = null;
}
}
}
*/
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
/*
Quota[] qa = new Quota[v.size()];
v.copyInto(qa);
return qa;
*/
|
public void | startTLS()STARTTLS Command.
try {
super.startTLS("STARTTLS");
} catch (ProtocolException pex) {
// ProtocolException just means the command wasn't recognized,
// or failed. This should never happen if we check the
// CAPABILITY first.
throw pex;
} catch (Exception ex) {
// any other exception means we have to shut down the connection
// generate an artificial BYE response and disconnect
Response[] r = { Response.byeResponse(ex) };
notifyResponseHandlers(r);
disconnect();
}
|
public com.sun.mail.imap.protocol.Status | status(java.lang.String mbox, java.lang.String[] items)STATUS Command.
if (!isREV1() && !hasCapability("IMAP4SUNVERSION"))
// STATUS is rev1 only, however the non-rev1 SIMS2.0
// does support this.
throw new BadCommandException("STATUS not supported");
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
Argument args = new Argument();
args.writeString(mbox);
Argument itemArgs = new Argument();
if (items == null)
items = Status.standardItems;
for (int i = 0, len = items.length; i < len; i++)
itemArgs.writeAtom(items[i]);
args.writeArgument(itemArgs);
Response[] r = command("STATUS", args);
Status status = null;
Response response = r[r.length-1];
// Grab all STATUS responses
if (response.isOK()) { // command succesful
for (int i = 0, len = r.length; i < len; i++) {
if (!(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("STATUS")) {
if (status == null)
status = new Status(ir);
else // collect 'em all
Status.add(status, new Status(ir));
r[i] = null;
}
}
}
// dispatch remaining untagged responses
notifyResponseHandlers(r);
handleResult(response);
return status;
|
public void | storeFlags(com.sun.mail.imap.protocol.MessageSet[] msgsets, javax.mail.Flags flags, boolean set)
storeFlags(MessageSet.toString(msgsets), flags, set);
|
public void | storeFlags(int start, int end, javax.mail.Flags flags, boolean set)
storeFlags(String.valueOf(start) + ":" + String.valueOf(end),
flags, set);
|
public void | storeFlags(int msg, javax.mail.Flags flags, boolean set)Set the specified flags on this message.
storeFlags(String.valueOf(msg), flags, set);
|
private void | storeFlags(java.lang.String msgset, javax.mail.Flags flags, boolean set)
Response[] r;
if (set)
r = command("STORE " + msgset + " +FLAGS " +
createFlagList(flags), null);
else
r = command("STORE " + msgset + " -FLAGS " +
createFlagList(flags), null);
// Dispatch untagged responses
notifyResponseHandlers(r);
handleResult(r[r.length-1]);
|
public void | subscribe(java.lang.String mbox)SUBSCRIBE Command.
Argument args = new Argument();
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
args.writeString(mbox);
simpleCommand("SUBSCRIBE", args);
|
protected boolean | supportsNonSyncLiterals()Returns whether this Protocol supports non-synchronizing literals.
return hasCapability("LITERAL+");
|
public void | uidexpunge(com.sun.mail.imap.protocol.UIDSet[] set)UID EXPUNGE Command.
if (!hasCapability("UIDPLUS"))
throw new BadCommandException("UID EXPUNGE not supported");
simpleCommand("UID EXPUNGE " + UIDSet.toString(set), null);
|
public void | unsubscribe(java.lang.String mbox)UNSUBSCRIBE Command.
Argument args = new Argument();
// encode the mbox as per RFC2060
mbox = BASE64MailboxEncoder.encode(mbox);
args.writeString(mbox);
simpleCommand("UNSUBSCRIBE", args);
|