📄 pop3.java
字号:
package com.jthomas.pop;
/*
* 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.*;
/**
*
* <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>
*
* <p>Interface to a POP3 mail server. Can be used to check, fetch
* and delete mail messages.
* 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.13 $ $Date: 1998/09/02 08:05:29 $
* @see apop
*/
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.<br>
* 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.<br>
* 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
popStatus statStatus = 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
String[] tokens = 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();
int i=0;
send("LIST " + msgnum); // Issue the LIST n command
status._Response = recv(); // read the response
String[] tokens = 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() {
popStatus status = new popStatus();
send("LIST"); // Issue the LIST command
recvN(status); // read the response
String[] tokens = Parse(status,2);
return status;
}
//----------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -