📄 pop3.java
字号:
package org.rapla.components.mail;
/*
* Pop3.java
* Copyright (c) 1996 John Thomas jthomas@cruzio.com
* All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for commercial or non-commercial purposes
* is hereby granted provided that this copyright notice
* appears in all copies.
*
* LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO
* LEGAL THEORY, SHALL THE AUTHOR OF THIS CLASS BE LIABLE TO YOU
* OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES OF ANY KIND.
*
*/
import java.io.*;
import java.util.*;
import java.net.*;
/** Interface to a Pop3 mail server. Can be used to check, fetch and delete mail messages.
* <p>Get the latest version of this and other classes in
* <a href="http://www.geocities.com/SunsetStrip/Studio/4994/java.html">
* Stefano Locati's Java page.</a>
*
* Based on the
* <a href="http://ds.internic.net/rfc/rfc1939.txt">rfc1939.txt</a>
* definition for the Post Office Protocol - Version 3 (obsoletes
* RFC 1725).
* <b>If mailhost, user, password are not supplied to the
* constructor, then they must be specified on the connect and
* login calls.</b>
*
* <p>The <code>Apop</code> command is not supported by the
* <code>Pop3</code> class. But there is an <code>Apop</code> class
* that extends <code>Pop3</code> to add <code>Apop</code> support.
* It can be used just like the pop class, just create an Apop object
* instead a pop object. The Apop class still works even if the
* <code>Pop3</code> server doesn't support <code>Apop</code> login.
*
* <p>Simple Usage Example to display the size of each message.
* <pre>
* Pop3 pop = new Pop3(host, user, password);
* PopStatus status = pop.connect();
* if ( status.OK() )
* status = pop.login();
* if ( status.OK() ) {
* status = pop.list();
* String[] responses = status.Responses();
* for(int i=0; i< responses.length; i++) {
* System.out.println("Message[" + i + "]='" + responses[i] + "'");
* }
* status = pop.quit();
* }
* </pre>
*
* <p>The following methods try to closely implement the corresponding
* Pop3 server commands. See RFC1939.
*
* <pre>
* PopStatus stat()
* PopStatus list()
* PopStatus list(msgnum)
* PopStatus retr(msgnum)
* PopStatus dele(msgnum)
* PopStatus noop()
* PopStatus quit()
* PopStatus top(msgnum,numlines)
* PopStatus uidl(msgnum)
* </pre>
*
* <ul><li>The indicated methods have additional multiline output
* that can be retrieved with the get_Responses method for
* the PopStatus object. i.e.
* <pre>
* PopStatus status = mypopserver.list()
* String[] list = status.get_Responses()
* </pre>
*
* <li>The following methods are convenience functions for the client
* <pre>
* PopStatus appendFile(filename,msgnum)
*
* int get_TotalMsgs() Number of mail messages on server
* int get_TotalSize() Total size of all mail messages
* _TotalSize and _TotalMsgs are set during
* login() by an internal stat() command
* </pre>
*
* <li>The status of a POP request is returned in an instance of
* the PopStatus class.
* PopStatus has the following methods to extract the returned info.
* <pre>
* boolean OK() True if request had no errors
* String Response() The initial line returned by POP server
* that starts with either +OK or -ERR
* String[] Responses() If command returns multiple lines of
* data (RETR, TOP, LIST) then this method
* will return the lines in an array.
* </pre>
*
* <li>Public debugging Methods.
* <pre>
* void setDebugOn(boolean) turn on debug output
* void set_DebugFile(filename) Set filename for debug output
* void debug(String DebugInfo) Display string on stdout
* </pre>
* </ul>
*
* @author <b>Original author:</b> John Thomas
* <a href="mailto:jthomas@cruzio.com">jthomas@cruzio.com</a>
* @author <b>Current maintainer:</b> Stefano Locati
* <a href="mailto:slocati@geocities.com">slocati@geocities.com</a> or
* <a href="mailto:stefano.locati@usa.net">stefano.locati@usa.net</a>
* @version $Revision: 1.4 $ $Date: 2004/09/28 09:34:47 $
*
*
*/
public
class Pop3 {
/** Authorization State */
protected final int AUTHORIZATION = 1;
/** Transaction State */
protected final int TRANSACTION = 2;
/** Update State */
protected final int UPDATE = 3;
/** Number of mail messages on server */
protected int _TotalMsgs = 0;
/** Total size of all messages on server */
protected int _TotalSize = 0;
/** status used by Send/Recv */
protected boolean _StatusOK = false;
/** Session State */
protected int State = 0;
/** The last Pop3 command sent to the server */
protected String LastCmd;
/** Pop3 server host name */
protected String Host = null;
/** Port on which the Pop3 server listens to */
protected int Port = 110;
/** Mailbox user name */
protected String User = null;
/** Mailbox password */
protected String Password = null;
/** Socket connected to the server */
protected Socket server;
/** Input stream connected to the server socket */
protected BufferedReader serverInputStream;
/** Output stream connected to the server socket */
protected DataOutputStream serverOutputStream;
/** debug On switch */
private boolean debugOn=false;
/**
* Creates the object. No work is done.
* @param host a Pop3 server host name
* @param user a mailbox user name
* @param password a mailbox password
*/
public Pop3(String host, String user, String password) {
Host = host;
User = user;
Password = password;
}
/**
* Creates the object. No work is done
* You will have to supply host, user and password through
* connect() and login() methods.
* @see #connect(java.lang.String)
* @see #login(java.lang.String, java.lang.String)
*/
public Pop3() {
}
/**
* Makes a socket connection to the specified
* host (port 110).
* @param host a Pop3 server host name
* @return PopStatus: result of this operation
*/
public PopStatus connect(String host) {
// If method specifies the host name then save it and
// call the default connect method
Host = host;
return this.connect();
}
/**
* Makes a socket connection to the specified
* host and port.
* @param host Pop3 server host name
* @param port TCP port to connect to
* @return PopStatus: result of this operation
*/
public PopStatus connect(String host, int port) {
// If both host and port are specified then save them
// and then call the default connect method
Host = host;
Port = port; // Normally this would be 110 (RFC 1725)
return this.connect();
}
/**
* Makes a socket connection to the host specified
* in the constructor (port 110).
* @return PopStatus: result of this operation
*/
public synchronized PopStatus connect() {
PopStatus status = new PopStatus();
debug("Connecting to " + Host + " at port " + Port);
if (Host == null) {
status._Response = "-ERR Host not specified";
status._OK = false;
return status;
}
try {
server = new Socket(Host,Port);
if (server == null) { // a failure with no exception????
debug("-ERR Error while connecting to Pop3 server");
status._OK = false;
status._Response = "-ERR Error while connecting to Pop3 server";
} else {
debug("Connected");
// get the input stream that we will use to read from the server
serverInputStream = new BufferedReader(
new InputStreamReader(server.getInputStream()));
if (serverInputStream == null) {
debug("Failed to setup an input stream.");
status._OK = false;
status._Response = "-ERR Error setting up input stream";
server = null;
}
serverOutputStream = new DataOutputStream(
server.getOutputStream() );
if (serverOutputStream == null) {
debug("Failed to setup an output stream.");
status._OK = false;
status._Response = "-ERR Error setting up output stream";
server = null;
}
}
}
catch (Exception e) {
String msg = "Exception! " + e.toString();
debug(msg);
status._OK = false;
status._Response = msg;
server = null;
}
if (server != null) {
status._OK = true;
// POP protocol requires server to send a response on the
// connect. We will now get that response and parse it
_StatusOK = true; // Fake doing send() before recv()
status._Response = recv();
Parse(status,2);
debug("Response=" + status._Response);
}
if (status._OK)
State = AUTHORIZATION;
return status;
}
/** Login the specified user with the specified password.
* If the login is successful, a STAT command is issued
* to get the current number of messages.
* @param user a mailbox user name
* @param password a mailbox password
* @return PopStatus: result of this operation
*/
public PopStatus
login(String user, String password) {
User = user;
Password = password;
return login();
}
/** Login with the user and password specified in the constructor.
* If the login is successful, a <code>STAT</code>
* command is issued to get the current number of
* messages.
* @return PopStatus: result of this operation
*/
public synchronized PopStatus login() {
PopStatus status = new PopStatus();
if (User == null || Password == null) {
status._Response = "-ERR Userid or Password not specified";
return status;
}
if ( server != null ) {
send("USER " + User);
status._Response = recv();
Parse(status,1);
if (status._OK) {
send("PASS " + Password);
status._Response = recv();
Parse(status,1);
if (status._OK) {
State = TRANSACTION;
// Now we will do an internal STAT function
stat();
}
}
}
return status;
}
/** Closes the socket connection.
* Use <code>quit</code> for a normal termination.
* @see #quit()
*/
public synchronized void close() {
debug("Closing socket");
try {
server.close();
State = 0;
} catch (IOException e) {
debug("Failure in server.close()");
}
}
/** Gets the number of messages and their total size from the server.
* @return PopStatus: result of this operation
*/
public synchronized PopStatus stat() {
PopStatus status = new PopStatus();
if (State != TRANSACTION) {
status._Response = "-ERR Server not in transaction mode";
return status;
}
send("STAT"); // Issue the STAT command
status._Response = recv(); // read the response
String[] tokens = Parse(status, 4);
if (status._OK) {
_TotalMsgs = Convert.toInt(tokens[1]);
_TotalSize = Convert.toInt(tokens[2]);
}
return status;
}
/**
* Quits the session with the Pop3 server.
* After receiving a goodbye message from the server,
* the socket is closed.
* @return PopStatus
*/
public synchronized PopStatus quit() {
PopStatus status = new PopStatus();
send("QUIT"); // Issue the STAT command
State = UPDATE;
status._Response = recv(); // read the response
Parse(status,2);
close();
return status;
}
/**
* Gets the size of the specified mail message.
* @param msgnum message number
* @return PopStatus: result of this operation
*/
public synchronized PopStatus list(int msgnum) {
PopStatus status = new PopStatus();
send("LIST " + msgnum); // Issue the LIST n command
status._Response = recv(); // read the response
Parse(status,2);
return status;
}
/** Gets a list of messages and the size of each one.
* @return PopStatus: result of this operation
*/
public synchronized PopStatus list() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -