From 063284837c8c366e5502b1b0264b8eb807b61732 Mon Sep 17 00:00:00 2001 From: Joe Robinson Date: Wed, 27 Oct 2010 14:21:09 +0100 Subject: Basic upload functionality to predifined location, with basic file browser --- org/apache/commons/net/pop3/POP3.java | 358 +++++++++++++++ org/apache/commons/net/pop3/POP3Client.java | 552 +++++++++++++++++++++++ org/apache/commons/net/pop3/POP3Command.java | 72 +++ org/apache/commons/net/pop3/POP3MessageInfo.java | 82 ++++ org/apache/commons/net/pop3/POP3Reply.java | 38 ++ 5 files changed, 1102 insertions(+) create mode 100644 org/apache/commons/net/pop3/POP3.java create mode 100644 org/apache/commons/net/pop3/POP3Client.java create mode 100644 org/apache/commons/net/pop3/POP3Command.java create mode 100644 org/apache/commons/net/pop3/POP3MessageInfo.java create mode 100644 org/apache/commons/net/pop3/POP3Reply.java (limited to 'org/apache/commons/net/pop3') diff --git a/org/apache/commons/net/pop3/POP3.java b/org/apache/commons/net/pop3/POP3.java new file mode 100644 index 0000000..80033ab --- /dev/null +++ b/org/apache/commons/net/pop3/POP3.java @@ -0,0 +1,358 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net.pop3; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.Enumeration; +import java.util.Vector; + +import org.apache.commons.net.MalformedServerReplyException; +import org.apache.commons.net.ProtocolCommandListener; +import org.apache.commons.net.ProtocolCommandSupport; +import org.apache.commons.net.SocketClient; + +/*** + * The POP3 class is not meant to be used by itself and is provided + * only so that you may easily implement your own POP3 client if + * you so desire. If you have no need to perform your own implementation, + * you should use {@link org.apache.commons.net.pop3.POP3Client}. + *

+ * Rather than list it separately for each method, we mention here that + * every method communicating with the server and throwing an IOException + * can also throw a + * {@link org.apache.commons.net.MalformedServerReplyException} + * , which is a subclass + * of IOException. A MalformedServerReplyException will be thrown when + * the reply received from the server deviates enough from the protocol + * specification that it cannot be interpreted in a useful manner despite + * attempts to be as lenient as possible. + *

+ *

+ * @author Daniel F. Savarese + * @see POP3Client + * @see org.apache.commons.net.MalformedServerReplyException + ***/ + +public class POP3 extends SocketClient +{ + /*** The default POP3 port. Set to 110 according to RFC 1288. ***/ + public static final int DEFAULT_PORT = 110; + /*** + * A constant representing the state where the client is not yet connected + * to a POP3 server. + ***/ + public static final int DISCONNECTED_STATE = -1; + /*** A constant representing the POP3 authorization state. ***/ + public static final int AUTHORIZATION_STATE = 0; + /*** A constant representing the POP3 transaction state. ***/ + public static final int TRANSACTION_STATE = 1; + /*** A constant representing the POP3 update state. ***/ + public static final int UPDATE_STATE = 2; + + static final String _OK = "+OK"; + static final String _ERROR = "-ERR"; + + // We have to ensure that the protocol communication is in ASCII + // but we use ISO-8859-1 just in case 8-bit characters cross + // the wire. + private static final String __DEFAULT_ENCODING = "ISO-8859-1"; + + private int __popState; + private BufferedWriter __writer; + private StringBuffer __commandBuffer; + + BufferedReader _reader; + int _replyCode; + String _lastReplyLine; + Vector _replyLines; + + /*** + * A ProtocolCommandSupport object used to manage the registering of + * ProtocolCommandListeners and te firing of ProtocolCommandEvents. + ***/ + protected ProtocolCommandSupport _commandSupport_; + + /*** + * The default POP3Client constructor. Initializes the state + * to DISCONNECTED_STATE. + ***/ + public POP3() + { + setDefaultPort(DEFAULT_PORT); + __commandBuffer = new StringBuffer(); + __popState = DISCONNECTED_STATE; + _reader = null; + __writer = null; + _replyLines = new Vector(); + _commandSupport_ = new ProtocolCommandSupport(this); + } + + private void __getReply() throws IOException + { + String line; + + _replyLines.setSize(0); + line = _reader.readLine(); + + if (line == null) + throw new EOFException("Connection closed without indication."); + + if (line.startsWith(_OK)) + _replyCode = POP3Reply.OK; + else if (line.startsWith(_ERROR)) + _replyCode = POP3Reply.ERROR; + else + throw new + MalformedServerReplyException( + "Received invalid POP3 protocol response from server."); + + _replyLines.addElement(line); + _lastReplyLine = line; + + if (_commandSupport_.getListenerCount() > 0) + _commandSupport_.fireReplyReceived(_replyCode, getReplyString()); + } + + + /*** + * Performs connection initialization and sets state to + * AUTHORIZATION_STATE . + ***/ + @Override + protected void _connectAction_() throws IOException + { + super._connectAction_(); + _reader = + new BufferedReader(new InputStreamReader(_input_, + __DEFAULT_ENCODING)); + __writer = + new BufferedWriter(new OutputStreamWriter(_output_, + __DEFAULT_ENCODING)); + __getReply(); + setState(AUTHORIZATION_STATE); + } + + + /*** + * Adds a ProtocolCommandListener. Delegates this task to + * {@link #_commandSupport_ _commandSupport_ }. + *

+ * @param listener The ProtocolCommandListener to add. + ***/ + public void addProtocolCommandListener(ProtocolCommandListener listener) + { + _commandSupport_.addProtocolCommandListener(listener); + } + + /*** + * Removes a ProtocolCommandListener. Delegates this task to + * {@link #_commandSupport_ _commandSupport_ }. + *

+ * @param listener The ProtocolCommandListener to remove. + ***/ + public void removeProtocolCommandistener(ProtocolCommandListener listener) + { + _commandSupport_.removeProtocolCommandListener(listener); + } + + + /*** + * Sets POP3 client state. This must be one of the + * _STATE constants. + *

+ * @param state The new state. + ***/ + public void setState(int state) + { + __popState = state; + } + + + /*** + * Returns the current POP3 client state. + *

+ * @return The current POP3 client state. + ***/ + public int getState() + { + return __popState; + } + + + /*** + * Retrieves the additional lines of a multi-line server reply. + ***/ + public void getAdditionalReply() throws IOException + { + String line; + + line = _reader.readLine(); + while (line != null) + { + _replyLines.addElement(line); + if (line.equals(".")) + break; + line = _reader.readLine(); + } + } + + + /*** + * Disconnects the client from the server, and sets the state to + * DISCONNECTED_STATE . The reply text information + * from the last issued command is voided to allow garbage collection + * of the memory used to store that information. + *

+ * @exception IOException If there is an error in disconnecting. + ***/ + @Override + public void disconnect() throws IOException + { + super.disconnect(); + _reader = null; + __writer = null; + _lastReplyLine = null; + _replyLines.setSize(0); + setState(DISCONNECTED_STATE); + } + + + /*** + * Sends a command an arguments to the server and returns the reply code. + *

+ * @param command The POP3 command to send. + * @param args The command arguments. + * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). + ***/ + public int sendCommand(String command, String args) throws IOException + { + String message; + + __commandBuffer.setLength(0); + __commandBuffer.append(command); + + if (args != null) + { + __commandBuffer.append(' '); + __commandBuffer.append(args); + } + __commandBuffer.append(SocketClient.NETASCII_EOL); + + __writer.write(message = __commandBuffer.toString()); + __writer.flush(); + + if (_commandSupport_.getListenerCount() > 0) + _commandSupport_.fireCommandSent(command, message); + + __getReply(); + return _replyCode; + } + + /*** + * Sends a command with no arguments to the server and returns the + * reply code. + *

+ * @param command The POP3 command to send. + * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). + ***/ + public int sendCommand(String command) throws IOException + { + return sendCommand(command, null); + } + + /*** + * Sends a command an arguments to the server and returns the reply code. + *

+ * @param command The POP3 command to send + * (one of the POP3Command constants). + * @param args The command arguments. + * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). + ***/ + public int sendCommand(int command, String args) throws IOException + { + return sendCommand(POP3Command._commands[command], args); + } + + /*** + * Sends a command with no arguments to the server and returns the + * reply code. + *

+ * @param command The POP3 command to send + * (one of the POP3Command constants). + * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). + ***/ + public int sendCommand(int command) throws IOException + { + return sendCommand(POP3Command._commands[command], null); + } + + + /*** + * Returns an array of lines received as a reply to the last command + * sent to the server. The lines have end of lines truncated. If + * the reply is a single line, but its format ndicates it should be + * a multiline reply, then you must call + * {@link #getAdditionalReply getAdditionalReply() } to + * fetch the rest of the reply, and then call getReplyStrings + * again. You only have to worry about this if you are implementing + * your own client using the {@link #sendCommand sendCommand } methods. + *

+ * @return The last server response. + ***/ + public String[] getReplyStrings() + { + String[] lines; + lines = new String[_replyLines.size()]; + _replyLines.copyInto(lines); + return lines; + } + + /*** + * Returns the reply to the last command sent to the server. + * The value is a single string containing all the reply lines including + * newlines. If the reply is a single line, but its format ndicates it + * should be a multiline reply, then you must call + * {@link #getAdditionalReply getAdditionalReply() } to + * fetch the rest of the reply, and then call getReplyString + * again. You only have to worry about this if you are implementing + * your own client using the {@link #sendCommand sendCommand } methods. + *

+ * @return The last server response. + ***/ + public String getReplyString() + { + Enumeration en; + StringBuffer buffer = new StringBuffer(256); + + en = _replyLines.elements(); + while (en.hasMoreElements()) + { + buffer.append(en.nextElement()); + buffer.append(SocketClient.NETASCII_EOL); + } + + return buffer.toString(); + } + +} + diff --git a/org/apache/commons/net/pop3/POP3Client.java b/org/apache/commons/net/pop3/POP3Client.java new file mode 100644 index 0000000..c5e9a96 --- /dev/null +++ b/org/apache/commons/net/pop3/POP3Client.java @@ -0,0 +1,552 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net.pop3; + +import java.io.IOException; +import java.io.Reader; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; +import java.util.StringTokenizer; + +import org.apache.commons.net.io.DotTerminatedMessageReader; + +/*** + * The POP3Client class implements the client side of the Internet POP3 + * Protocol defined in RFC 1939. All commands are supported, including + * the APOP command which requires MD5 encryption. See RFC 1939 for + * more details on the POP3 protocol. + *

+ * Rather than list it separately for each method, we mention here that + * every method communicating with the server and throwing an IOException + * can also throw a + * {@link org.apache.commons.net.MalformedServerReplyException} + * , which is a subclass + * of IOException. A MalformedServerReplyException will be thrown when + * the reply received from the server deviates enough from the protocol + * specification that it cannot be interpreted in a useful manner despite + * attempts to be as lenient as possible. + *

+ *

+ * @author Daniel F. Savarese + * @see POP3MessageInfo + * @see org.apache.commons.net.io.DotTerminatedMessageReader + * @see org.apache.commons.net.MalformedServerReplyException + ***/ + +public class POP3Client extends POP3 +{ + + private static POP3MessageInfo __parseStatus(String line) + { + int num, size; + StringTokenizer tokenizer; + + tokenizer = new StringTokenizer(line); + + if (!tokenizer.hasMoreElements()) + return null; + + num = size = 0; + + try + { + num = Integer.parseInt(tokenizer.nextToken()); + + if (!tokenizer.hasMoreElements()) + return null; + + size = Integer.parseInt(tokenizer.nextToken()); + } + catch (NumberFormatException e) + { + return null; + } + + return new POP3MessageInfo(num, size); + } + + private static POP3MessageInfo __parseUID(String line) + { + int num; + StringTokenizer tokenizer; + + tokenizer = new StringTokenizer(line); + + if (!tokenizer.hasMoreElements()) + return null; + + num = 0; + + try + { + num = Integer.parseInt(tokenizer.nextToken()); + + if (!tokenizer.hasMoreElements()) + return null; + + line = tokenizer.nextToken(); + } + catch (NumberFormatException e) + { + return null; + } + + return new POP3MessageInfo(num, line); + } + + /*** + * Login to the POP3 server with the given username and password. You + * must first connect to the server with + * {@link org.apache.commons.net.SocketClient#connect connect } + * before attempting to login. A login attempt is only valid if + * the client is in the + * {@link org.apache.commons.net.pop3.POP3#AUTHORIZATION_STATE AUTHORIZATION_STATE } + * . After logging in, the client enters the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . + *

+ * @param username The account name being logged in to. + * @param password The plain text password of the account. + * @return True if the login attempt was successful, false if not. + * @exception IOException If a network I/O error occurs in the process of + * logging in. + ***/ + public boolean login(String username, String password) throws IOException + { + if (getState() != AUTHORIZATION_STATE) + return false; + + if (sendCommand(POP3Command.USER, username) != POP3Reply.OK) + return false; + + if (sendCommand(POP3Command.PASS, password) != POP3Reply.OK) + return false; + + setState(TRANSACTION_STATE); + + return true; + } + + + /*** + * Login to the POP3 server with the given username and authentication + * information. Use this method when connecting to a server requiring + * authentication using the APOP command. Because the timestamp + * produced in the greeting banner varies from server to server, it is + * not possible to consistently extract the information. Therefore, + * after connecting to the server, you must call + * {@link org.apache.commons.net.pop3.POP3#getReplyString getReplyString } + * and parse out the timestamp information yourself. + *

+ * You must first connect to the server with + * {@link org.apache.commons.net.SocketClient#connect connect } + * before attempting to login. A login attempt is only valid if + * the client is in the + * {@link org.apache.commons.net.pop3.POP3#AUTHORIZATION_STATE AUTHORIZATION_STATE } + * . After logging in, the client enters the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . After connecting, you must parse out the + * server specific information to use as a timestamp, and pass that + * information to this method. The secret is a shared secret known + * to you and the server. See RFC 1939 for more details regarding + * the APOP command. + *

+ * @param username The account name being logged in to. + * @param timestamp The timestamp string to combine with the secret. + * @param secret The shared secret which produces the MD5 digest when + * combined with the timestamp. + * @return True if the login attempt was successful, false if not. + * @exception IOException If a network I/O error occurs in the process of + * logging in. + * @exception NoSuchAlgorithmException If the MD5 encryption algorithm + * cannot be instantiated by the Java runtime system. + ***/ + public boolean login(String username, String timestamp, String secret) + throws IOException, NoSuchAlgorithmException + { + int i; + byte[] digest; + StringBuffer buffer, digestBuffer; + MessageDigest md5; + + if (getState() != AUTHORIZATION_STATE) + return false; + + md5 = MessageDigest.getInstance("MD5"); + timestamp += secret; + digest = md5.digest(timestamp.getBytes()); + digestBuffer = new StringBuffer(128); + + for (i = 0; i < digest.length; i++) + digestBuffer.append(Integer.toHexString(digest[i] & 0xff)); + + buffer = new StringBuffer(256); + buffer.append(username); + buffer.append(' '); + buffer.append(digestBuffer.toString()); + + if (sendCommand(POP3Command.APOP, buffer.toString()) != POP3Reply.OK) + return false; + + setState(TRANSACTION_STATE); + + return true; + } + + + /*** + * Logout of the POP3 server. To fully disconnect from the server + * you must call + * {@link org.apache.commons.net.pop3.POP3#disconnect disconnect }. + * A logout attempt is valid in any state. If + * the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * , it enters the + * {@link org.apache.commons.net.pop3.POP3#UPDATE_STATE UPDATE_STATE } + * on a successful logout. + *

+ * @return True if the logout attempt was successful, false if not. + * @exception IOException If a network I/O error occurs in the process + * of logging out. + ***/ + public boolean logout() throws IOException + { + if (getState() == TRANSACTION_STATE) + setState(UPDATE_STATE); + sendCommand(POP3Command.QUIT); + return (_replyCode == POP3Reply.OK); + } + + + /*** + * Send a NOOP command to the POP3 server. This is useful for keeping + * a connection alive since most POP3 servers will timeout after 10 + * minutes of inactivity. A noop attempt will only succeed if + * the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . + *

+ * @return True if the noop attempt was successful, false if not. + * @exception IOException If a network I/O error occurs in the process of + * sending the NOOP command. + ***/ + public boolean noop() throws IOException + { + if (getState() == TRANSACTION_STATE) + return (sendCommand(POP3Command.NOOP) == POP3Reply.OK); + return false; + } + + + /*** + * Delete a message from the POP3 server. The message is only marked + * for deletion by the server. If you decide to unmark the message, you + * must issuse a {@link #reset reset } command. Messages marked + * for deletion are only deleted by the server on + * {@link #logout logout }. + * A delete attempt can only succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . + *

+ * @param messageId The message number to delete. + * @return True if the deletion attempt was successful, false if not. + * @exception IOException If a network I/O error occurs in the process of + * sending the delete command. + ***/ + public boolean deleteMessage(int messageId) throws IOException + { + if (getState() == TRANSACTION_STATE) + return (sendCommand(POP3Command.DELE, Integer.toString(messageId)) + == POP3Reply.OK); + return false; + } + + + /*** + * Reset the POP3 session. This is useful for undoing any message + * deletions that may have been performed. A reset attempt can only + * succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . + *

+ * @return True if the reset attempt was successful, false if not. + * @exception IOException If a network I/O error occurs in the process of + * sending the reset command. + ***/ + public boolean reset() throws IOException + { + if (getState() == TRANSACTION_STATE) + return (sendCommand(POP3Command.RSET) == POP3Reply.OK); + return false; + } + + /*** + * Get the mailbox status. A status attempt can only + * succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . Returns a POP3MessageInfo instance + * containing the number of messages in the mailbox and the total + * size of the messages in bytes. Returns null if the status the + * attempt fails. + *

+ * @return A POP3MessageInfo instance containing the number of + * messages in the mailbox and the total size of the messages + * in bytes. Returns null if the status the attempt fails. + * @exception IOException If a network I/O error occurs in the process of + * sending the status command. + ***/ + public POP3MessageInfo status() throws IOException + { + if (getState() != TRANSACTION_STATE) + return null; + if (sendCommand(POP3Command.STAT) != POP3Reply.OK) + return null; + return __parseStatus(_lastReplyLine.substring(3)); + } + + + /*** + * List an individual message. A list attempt can only + * succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . Returns a POP3MessageInfo instance + * containing the number of the listed message and the + * size of the message in bytes. Returns null if the list + * attempt fails (e.g., if the specified message number does + * not exist). + *

+ * @param messageId The number of the message list. + * @return A POP3MessageInfo instance containing the number of the + * listed message and the size of the message in bytes. Returns + * null if the list attempt fails. + * @exception IOException If a network I/O error occurs in the process of + * sending the list command. + ***/ + public POP3MessageInfo listMessage(int messageId) throws IOException + { + if (getState() != TRANSACTION_STATE) + return null; + if (sendCommand(POP3Command.LIST, Integer.toString(messageId)) + != POP3Reply.OK) + return null; + return __parseStatus(_lastReplyLine.substring(3)); + } + + + /*** + * List all messages. A list attempt can only + * succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . Returns an array of POP3MessageInfo instances, + * each containing the number of a message and its size in bytes. + * If there are no messages, this method returns a zero length array. + * If the list attempt fails, it returns null. + *

+ * @return An array of POP3MessageInfo instances representing all messages + * in the order they appear in the mailbox, + * each containing the number of a message and its size in bytes. + * If there are no messages, this method returns a zero length array. + * If the list attempt fails, it returns null. + * @exception IOException If a network I/O error occurs in the process of + * sending the list command. + ***/ + public POP3MessageInfo[] listMessages() throws IOException + { + POP3MessageInfo[] messages; + Enumeration en; + int line; + + if (getState() != TRANSACTION_STATE) + return null; + if (sendCommand(POP3Command.LIST) != POP3Reply.OK) + return null; + getAdditionalReply(); + + // This could be a zero length array if no messages present + messages = new POP3MessageInfo[_replyLines.size() - 2]; + en = _replyLines.elements(); + + // Skip first line + en.nextElement(); + + // Fetch lines. + for (line = 0; line < messages.length; line++) + messages[line] = __parseStatus(en.nextElement()); + + return messages; + } + + /*** + * List the unique identifier for a message. A list attempt can only + * succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . Returns a POP3MessageInfo instance + * containing the number of the listed message and the + * unique identifier for that message. Returns null if the list + * attempt fails (e.g., if the specified message number does + * not exist). + *

+ * @param messageId The number of the message list. + * @return A POP3MessageInfo instance containing the number of the + * listed message and the unique identifier for that message. + * Returns null if the list attempt fails. + * @exception IOException If a network I/O error occurs in the process of + * sending the list unique identifier command. + ***/ + public POP3MessageInfo listUniqueIdentifier(int messageId) + throws IOException + { + if (getState() != TRANSACTION_STATE) + return null; + if (sendCommand(POP3Command.UIDL, Integer.toString(messageId)) + != POP3Reply.OK) + return null; + return __parseUID(_lastReplyLine.substring(3)); + } + + + /*** + * List the unique identifiers for all messages. A list attempt can only + * succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . Returns an array of POP3MessageInfo instances, + * each containing the number of a message and its unique identifier. + * If there are no messages, this method returns a zero length array. + * If the list attempt fails, it returns null. + *

+ * @return An array of POP3MessageInfo instances representing all messages + * in the order they appear in the mailbox, + * each containing the number of a message and its unique identifier + * If there are no messages, this method returns a zero length array. + * If the list attempt fails, it returns null. + * @exception IOException If a network I/O error occurs in the process of + * sending the list unique identifier command. + ***/ + public POP3MessageInfo[] listUniqueIdentifiers() throws IOException + { + POP3MessageInfo[] messages; + Enumeration en; + int line; + + if (getState() != TRANSACTION_STATE) + return null; + if (sendCommand(POP3Command.UIDL) != POP3Reply.OK) + return null; + getAdditionalReply(); + + // This could be a zero length array if no messages present + messages = new POP3MessageInfo[_replyLines.size() - 2]; + en = _replyLines.elements(); + + // Skip first line + en.nextElement(); + + // Fetch lines. + for (line = 0; line < messages.length; line++) + messages[line] = __parseUID(en.nextElement()); + + return messages; + } + + + /*** + * Retrieve a message from the POP3 server. A retrieve message attempt + * can only succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . Returns a DotTerminatedMessageReader instance + * from which the entire message can be read. + * Returns null if the retrieval attempt fails (e.g., if the specified + * message number does not exist). + *

+ * You must not issue any commands to the POP3 server (i.e., call any + * other methods) until you finish reading the message from the + * returned Reader instance. + * The POP3 protocol uses the same stream for issuing commands as it does + * for returning results. Therefore the returned Reader actually reads + * directly from the POP3 connection. After the end of message has been + * reached, new commands can be executed and their replies read. If + * you do not follow these requirements, your program will not work + * properly. + *

+ * @param messageId The number of the message to fetch. + * @return A DotTerminatedMessageReader instance + * from which the entire message can be read. + * Returns null if the retrieval attempt fails (e.g., if the specified + * message number does not exist). + * @exception IOException If a network I/O error occurs in the process of + * sending the retrieve message command. + ***/ + public Reader retrieveMessage(int messageId) throws IOException + { + if (getState() != TRANSACTION_STATE) + return null; + if (sendCommand(POP3Command.RETR, Integer.toString(messageId)) + != POP3Reply.OK) + return null; + + return new DotTerminatedMessageReader(_reader); + } + + + /*** + * Retrieve only the specified top number of lines of a message from the + * POP3 server. A retrieve top lines attempt + * can only succeed if the client is in the + * {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE } + * . Returns a DotTerminatedMessageReader instance + * from which the specified top number of lines of the message can be + * read. + * Returns null if the retrieval attempt fails (e.g., if the specified + * message number does not exist). + *

+ * You must not issue any commands to the POP3 server (i.e., call any + * other methods) until you finish reading the message from the returned + * Reader instance. + * The POP3 protocol uses the same stream for issuing commands as it does + * for returning results. Therefore the returned Reader actually reads + * directly from the POP3 connection. After the end of message has been + * reached, new commands can be executed and their replies read. If + * you do not follow these requirements, your program will not work + * properly. + *

+ * @param messageId The number of the message to fetch. + * @param numLines The top number of lines to fetch. This must be >= 0. + * @return A DotTerminatedMessageReader instance + * from which the specified top number of lines of the message can be + * read. + * Returns null if the retrieval attempt fails (e.g., if the specified + * message number does not exist). + * @exception IOException If a network I/O error occurs in the process of + * sending the top command. + ***/ + public Reader retrieveMessageTop(int messageId, int numLines) + throws IOException + { + if (numLines < 0 || getState() != TRANSACTION_STATE) + return null; + if (sendCommand(POP3Command.TOP, Integer.toString(messageId) + " " + + Integer.toString(numLines)) != POP3Reply.OK) + return null; + + return new DotTerminatedMessageReader(_reader); + } + + +} + diff --git a/org/apache/commons/net/pop3/POP3Command.java b/org/apache/commons/net/pop3/POP3Command.java new file mode 100644 index 0000000..0f583bc --- /dev/null +++ b/org/apache/commons/net/pop3/POP3Command.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net.pop3; + +/*** + * POP3Command stores POP3 command code constants. + *

+ *

+ * @author Daniel F. Savarese + ***/ + +public final class POP3Command +{ + /*** Send user name. ***/ + public static final int USER = 0; + /*** Send password. ***/ + public static final int PASS = 1; + /*** Quit session. ***/ + public static final int QUIT = 2; + /*** Get status. ***/ + public static final int STAT = 3; + /*** List message(s). ***/ + public static final int LIST = 4; + /*** Retrieve message(s). ***/ + public static final int RETR = 5; + /*** Delete message(s). ***/ + public static final int DELE = 6; + /*** No operation. Used as a session keepalive. ***/ + public static final int NOOP = 7; + /*** Reset session. ***/ + public static final int RSET = 8; + /*** Authorization. ***/ + public static final int APOP = 9; + /*** Retrieve top number lines from message. ***/ + public static final int TOP = 10; + /*** List unique message identifier(s). ***/ + public static final int UIDL = 11; + + static final String[] _commands = { + "USER", "PASS", "QUIT", "STAT", "LIST", "RETR", "DELE", "NOOP", "RSET", + "APOP", "TOP", "UIDL" + }; + + // Cannot be instantiated. + private POP3Command() + {} + + /*** + * Get the POP3 protocol string command corresponding to a command code. + *

+ * @return The POP3 protocol string command corresponding to a command code. + ***/ + public static final String getCommand(int command) + { + return _commands[command]; + } +} diff --git a/org/apache/commons/net/pop3/POP3MessageInfo.java b/org/apache/commons/net/pop3/POP3MessageInfo.java new file mode 100644 index 0000000..070fd69 --- /dev/null +++ b/org/apache/commons/net/pop3/POP3MessageInfo.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net.pop3; + +/*** + * POP3MessageInfo is used to return information about messages stored on + * a POP3 server. Its fields are used to mean slightly different things + * depending on the information being returned. + *

+ * In response to a status command, number + * contains the number of messages in the mailbox, size + * contains the size of the mailbox in bytes, and identifier + * is null. + *

+ * In response to a message listings, number + * contains the message number, size contains the + * size of the message in bytes, and identifier is null. + *

+ * In response to unique identifier listings, number contains + * the message number, size is undefined, and + * identifier contains the message's unique identifier. + *

+ *

+ * @author Daniel F. Savarese + ***/ + +public final class POP3MessageInfo +{ + public int number; + public int size; + public String identifier; + + /*** + * Creates a POP3MessageInfo instance with number and + * size set to 0, and identifier set to + * null. + ***/ + public POP3MessageInfo() + { + number = size = 0; + identifier = null; + } + + /*** + * Creates a POP3MessageInfo instance with number set + * to num , size set to octets , + * and identifier set to null. + ***/ + public POP3MessageInfo(int num, int octets) + { + number = num; + size = octets; + identifier = null; + } + + /*** + * Creates a POP3MessageInfo instance with number set + * to num , size undefined, + * and identifier set to uid. + ***/ + public POP3MessageInfo(int num, String uid) + { + number = num; + size = -1; + identifier = uid; + } +} diff --git a/org/apache/commons/net/pop3/POP3Reply.java b/org/apache/commons/net/pop3/POP3Reply.java new file mode 100644 index 0000000..08e4246 --- /dev/null +++ b/org/apache/commons/net/pop3/POP3Reply.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.net.pop3; + +/*** + * POP3Reply stores POP3 reply code constants. + *

+ *

+ * @author Daniel F. Savarese + ***/ + +public final class POP3Reply +{ + /*** The reply code indicating success of an operation. ***/ + public static final int OK = 0; + + /*** The reply code indicating failure of an operation. ***/ + public static final int ERROR = 1; + + // Cannot be instantiated. + private POP3Reply() + {} +} -- cgit v1.2.3