📄 imapprotocol.java
字号:
// 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; } /** * SASL-based login. */ public void sasllogin(String[] allowed, String realm, String authzid, String u, String p) throws ProtocolException { 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; } // XXX - for IMAPSaslAuthenticator access to protected method OutputStream getIMAPOutputStream() { return getOutputStream(); } /** * PROXYAUTH Command. * * @see "Netscape/iPlanet/SunONE Messaging Server extension" */ public void proxyauth(String u) throws ProtocolException { Argument args = new Argument(); args.writeString(u); simpleCommand("PROXYAUTH", args); } /** * STARTTLS Command. * * @see "RFC3501, section 6.2.1" */ public void startTLS() throws ProtocolException { 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(); } } /** * SELECT Command. * * @see "RFC2060, section 6.3.1" */ public MailboxInfo select(String mbox) throws ProtocolException { // 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; } /** * EXAMINE Command. * * @see "RFC2060, section 6.3.2" */ public MailboxInfo examine(String mbox) throws ProtocolException { // 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; } /** * STATUS Command. * * @see "RFC2060, section 6.3.10" */ public Status status(String mbox, String[] items) throws ProtocolException { 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; } /** * CREATE Command. * * @see "RFC2060, section 6.3.3" */ public void create(String mbox) throws ProtocolException { // encode the mbox as per RFC2060 mbox = BASE64MailboxEncoder.encode(mbox); Argument args = new Argument(); args.writeString(mbox); simpleCommand("CREATE", args); } /** * DELETE Command. * * @see "RFC2060, section 6.3.4" */ public void delete(String mbox) throws ProtocolException { // encode the mbox as per RFC2060 mbox = BASE64MailboxEncoder.encode(mbox); Argument args = new Argument(); args.writeString(mbox); simpleCommand("DELETE", args); } /** * RENAME Command. * * @see "RFC2060, section 6.3.5" */ public void rename(String o, String n) throws ProtocolException { // 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); } /** * SUBSCRIBE Command. * * @see "RFC2060, section 6.3.6" */ public void subscribe(String mbox) throws ProtocolException { Argument args = new Argument(); // encode the mbox as per RFC2060 mbox = BASE64MailboxEncoder.encode(mbox); args.writeString(mbox); simpleCommand("SUBSCRIBE", args); } /** * UNSUBSCRIBE Command. * * @see "RFC2060, section 6.3.7" */ public void unsubscribe(String mbox) throws ProtocolException { Argument args = new Argument(); // encode the mbox as per RFC2060 mbox = BASE64MailboxEncoder.encode(mbox); args.writeString(mbox); simpleCommand("UNSUBSCRIBE", args); } /** * LIST Command. * * @see "RFC2060, section 6.3.8" */ public ListInfo[] list(String ref, String pattern) throws ProtocolException { return doList("LIST", ref, pattern); } /** * LSUB Command. * * @see "RFC2060, section 6.3.9" */ public ListInfo[] lsub(String ref, String pattern) throws ProtocolException { return doList("LSUB", ref, pattern); } private ListInfo[] doList(String cmd, String ref, String pat) throws ProtocolException { // 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; } /** * APPEND Command. * * @see "RFC2060, section 6.3.11" */ public void append(String mbox, Flags f, Date d, Literal data) throws ProtocolException { appenduid(mbox, f, d, data, false); // ignore return value } /** * APPEND Command, return uid from APPENDUID response code. * * @see "RFC2060, section 6.3.11" */ public AppendUID appenduid(String mbox, Flags f, Date d, Literal data) throws ProtocolException { return appenduid(mbox, f, d, data, true); } public AppendUID appenduid(String mbox, Flags f, Date d, Literal data, boolean uid) throws ProtocolException { // 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; } /** * If the response contains an APPENDUID response code, extract * it and return an AppendUID object with the information. */ private AppendUID getAppendUID(Response r) { 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); } /** * CHECK Command. * * @see "RFC2060, section 6.4.1" */ public void check() throws ProtocolException { simpleCommand("CHECK", null); } /** * CLOSE Command. * * @see "RFC2060, section 6.4.2" */ public void close() throws ProtocolException { simpleCommand("CLOSE", null); } /** * EXPUNGE Command. * * @see "RFC2060, section 6.4.3" */ public void expunge() throws ProtocolException { simpleCommand("EXPUNGE", null); } /** * UID EXPUNGE Command. * * @see "RFC2359, section 4.1" */ public void uidexpunge(UIDSet[] set) throws ProtocolException { if (!hasCapability("UIDPLUS")) throw new BadCommandException("UID EXPUNGE not supported"); simpleCommand("UID EXPUNGE " + UIDSet.toString(set), null); } /** * Fetch the BODYSTRUCTURE of the specified message. */ public BODYSTRUCTURE fetchBodyStructure(int msgno) throws ProtocolException { 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; } } /** * Fetch given BODY section, without marking the message * as SEEN. */ public BODY peekBody(int msgno, String section) throws ProtocolException { return fetchBody(msgno, section, true); } /** * Fetch given BODY section. */ public BODY fetchBody(int msgno, String section) throws ProtocolException { return fetchBody(msgno, section, false); } protected BODY fetchBody(int msgno, String section, boolean peek) throws ProtocolException { 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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -